二叉树遍历非递归写法

前序和中序比较简单
使用一个if else即可判断 一直往左走就行了

但是后序比较麻烦,因为最后访问根节点,涉及到一个走过的根节点重新访问
如何知道我是第二次到达根节点访问,而不是节点左右子树还有没有访问过呢?
实际上如果这个节点是第二次到达访问,即左子树肯定已经访问过出栈,不存在了
只有可能右子树是没有访问过了,即我们用一个pre指针,指向已经访问过的上一个节点记录一下就行了,如果p->right==NULLp->right==pre 说明这个点肯定需要访问,因为右子树被访问过了 或者根本没有右子树
代码如下:

#include<iostream>
#include<stack>

using namespace std;

struct TreeNode
{
    TreeNode *left;
    TreeNode *right;
    int val;
    TreeNode(int v):val(v),left(NULL),right(NULL){}
};

void preorder(TreeNode* root)
{
    stack<TreeNode*> stk;
    TreeNode *p = root;
    TreeNode *pre = p; 
    while(p || !stk.empty())
    {
        if(p)
        {
            cout<<p->val<<" ";
            stk.push(p);
            p = p->left;
        }
        else
        {
            p = stk.top()->right;//往右走
            stk.pop();
        }
    }
}

void inorder(TreeNode* root)
{
    stack<TreeNode*> stk;
    TreeNode *p = root;
    TreeNode *pre = p; 
    while(p || !stk.empty())
    {
        if(p)
        {
            
            stk.push(p);
            p = p->left;
        }
        else
        {
            p = stk.top();
            cout<<p->val<<" "; //访问
            p = p->right;
            stk.pop();
        }
    }
}
void postorder(TreeNode* root)
{
    stack<TreeNode*> stk;
    TreeNode *p = root;
    TreeNode *pre = p;
    while(p || !stk.empty())
    {
        while(p) //不能用if else了 
        {
            stk.push(p);
            p = p->left;
        }
        p = stk.top();
     
        if(p->right==NULL || p->right==pre)
        {
            cout<<p->val<<" ";
            stk.pop();
            pre = p;
            p = NULL;
        }
        else
        {
            p = p->right;
        }
    }
}


int main()
{
    TreeNode *root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    /*
      1
     2 3
    4 5
    */
    TreeNode *p = root->left;
    p->left = new TreeNode(4);
    p->right = new TreeNode(5);
    TreeNode *q = root->right;
    q->left = new TreeNode(6);
    q->right = new TreeNode(7);
    cout<<"后序"<<endl;
    postorder(root);
    cout<<endl;
    cout<<"前序"<<endl;
    preorder(root);
    cout<<endl;
    cout<<"中序"<<endl;
    inorder(root);
    return 0;
    
}
上一篇:Ubuntu 11.04 安装后要做的20件事情


下一篇:本篇博客记录的是我写过的LeetCode中关于栈的题