非递归遍历的原理是借助一个辅助栈
先从中序遍历看起,中序遍历是左根右
如果当前二叉树有左子树,那么就入栈。
如果没有左子数,那么先输出当前栈顶元素,然后p在走到右子数,不断的重复这个过程,说实话这个代码不好想
vector inorderTraversal(TreeNode* root) {
vector res;
stack st;
while(root||!st.empty()){
while(root!=NULL){
st.push(root);
root = root->left;
}
root = st.top();
st.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
非递归的前序遍历和中序遍历是很像的,只要改一个地方,每次先输出当前节点元素即可。
class Solution {
public:
vector preorderTraversal(TreeNode* root) {
vector res;
stack st;
while(root||!st.empty()){
while(root!=NULL){
res.push_back(root->val);
st.push(root);
root = root->left;
}
root = st.top();
st.pop();
root = root->right;
}
return res;
}
};
后序遍历是比较难的,左右根,是先添加左儿子,在添加右儿子,在回溯的时候添加根节点,我们并不知道什么时候右子数已经遍历完。
所以一般有经验的面试管不会考后序遍历的非递归写法
存在一个取巧的办法:
前序遍历是 根左右
后序遍历是 左右根
将后续遍历翻转正好是 根右左,可以用前序遍历实现。
class Solution {
public:
vector postorderTraversal(TreeNode* root) {
vector res;
stack st;
while(root||!st.empty()){
while(root!=NULL){
res.push_back(root->val);
st.push(root);
root = root->right;
}
root = st.top();
st.pop();
root = root->left;
}
reverse(res.begin(),res.end());
return res;
}
};