二叉树前序遍历、中序遍历、后序遍历的迭代版
- 前序遍历
void preorder(TreeNode* root)
{
if(root==NULL)
return;
stack<TreeNode*> s;
while(root||!s.empty())
{
while(root)
{
//...处理root
s.push(root);
root=root->left;
}
root=s.top();
s.pop();
root=root->right;
}
}
- 中序遍历
void midorder(TreeNode* root)
{
if(root)
cout<<"empty!"<<endl;
stack<int> s;
while(root||!s.empty())
{
while(root)
{
s.push(root);
root=root->left;
}
root=s.top();
s.pop();
//...处理root
root=root->right;
}
}
- 后序遍历
void postorder(TreeNode* root)
{
stack<TreeNode*> s;
TreeNode * p = root;
TreeNode * lastVisited = NULL;//记录上一次访问过的节点
if(p == NULL)
return ans;
while(!s.empty() || p)
{
//不断往左孩子迭代,直到左孩子为空,同时路径上的节点入栈
if(p)
{
s.push(p);
p = p->left;
}
//此时p==NULL,到达了左下角节点
else
{
p = stk.top();
//右孩子为空,或者右孩子上次已经访问完
if(p->right == NULL || p->right == lastVisited)
{
//...处理p
lastVisited = p;//更新lastVisited
s.pop();
p = NULL;
}
else{
p = p->right;//这时p是第一次被访问,不能直接访问其指向的值,应该先访问右子树
}
}
}
return ans;
}
前序遍历和中序遍历基本一样,访问节点位置不一样,后序遍历相对复杂,关键在于lastvisited的追踪。