1、先序非递归
先序遍历:根->左->右
先序非递归最简单,使用栈保存节点。节点出栈后,直接访问(输出值或者保存下来),然后将右孩子加入栈,再将左孩子加入栈(注意左右的顺序)。
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
//* Definition for binary tree
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
TreeNode *tmp;
stack<TreeNode*> s;
vector<int> v;
if(!root)return v;
s.push(root);
while(!s.empty()){
tmp = s.top();
s.pop();
v.push_back(tmp->val);
TreeNode *left = tmp->left, *right = tmp->right;
if(right) s.push(right);
if(left) s.push(left);
}
return v;
}
};
int main(){
TreeNode a(1), b(2), c(3), d(4), e(5);
a.left = &b, a.right = &c, b.right = &d, b.left = &e;
Solution s;
vector<int> ans = s.preorderTraversal(&a);
for(int i = 0; i < ans.size(); i++)
cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
2、中序非递归
中序遍历:左->根->右
还是使用栈来存储节点,从当前节点一直往左孩子走,将左孩子加入栈中,如果左孩子为空了,则出栈访问这个元素,并进入右孩子节点,继续上面的流程。
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
stack<TreeNode*> s;
vector<int> ans;
TreeNode *tmp = root;
while(tmp || !s.empty()){
while(tmp){
s.push(tmp);
tmp = tmp->left;
}
if(!s.empty()){
tmp = s.top();
s.pop();
ans.push_back(tmp->val);
tmp = tmp->right;
}
}
return ans;
}
};
3、后序非递归
后序遍历:左->右->根
还是使用栈保存节点,另外加一个pre指针指向上一个访问的节点。如果栈顶元素左右孩子都为空,那么可以访问它;或者pre是它的右孩子或左孩子(没有右孩子的时候才会出现pre是当前节点左孩子的情况),那么说明孩子节点都已访问完,也可以访问它。否则的话,不能访问栈顶节点,需要将它的右孩子和左孩子分别加入栈中。
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
TreeNode *tmp, *pre = NULL;
stack<TreeNode*> s;
vector<int> ans;
if(!root)return ans;
s.push(root);
while(!s.empty()){
tmp = s.top();
if(tmp->left==NULL && tmp->right==NULL || pre!=NULL && (pre==tmp->left||pre==tmp->right)){
ans.push_back(tmp->val);
s.pop();
pre = tmp;
}else{
if(tmp->right) s.push(tmp->right);
if(tmp->left) s.push(tmp->left);
}
}
return ans;
}
};