二叉树非递归后序遍历

先来看一下递归版的后序遍历是怎么写的

void dfs(TreeNode *root){
    if(root==NULL) return ;
    dfs(root->left);//左节点
    dfs(root->right);//右节点
    cout<<roo->val<<endl;//访问
}

可以看到,对于root,我们总是先访问root的left儿子,right儿子,然后再访问root,也就是说,我们第三次看到root时候再对它进行访问。

非递归的思想其实是一样的,当我们第一次遇到root的时候,如果有左儿子,先将root搁置,然后去访问它的左儿子,再遇到root的时候再将它搁置,去访问它的右儿子,再三次遇到rootd的时候,访问root,所谓搁置,就是将该节点放到stack中,当某一个之路访问完毕后,也就是遇到NULL节点时,从stack中取出之前每访问的节点,然后再接着上次访问。

记录某个节点出现的次数,我们可以借用map。

code:

class Solution {
    vector<int> ans;
public:
    stack<TreeNode*>st;
    map<TreeNode*,int >mp;
    vector<int> postorderTraversal(TreeNode* root) {
        mp.clear();
        if(!root) return ans;
        TreeNode* mark=NULL;
        while(root||st.size()){
            if(root){//第一次遇到root,访问它的左儿子
                st.push(root);
                mp[root]++;
                root=root->left;
            }
            else {
                while(st.size()){
                    TreeNode* p=st.top();
                    st.pop();
                    if(mp[p]==2||p->right==NULL){//如果说第三次遇到p,或者说该节点没有右节点,那么可以直接访问
                        ans.push_back(p->val);
                    }
                    else {//说明第二次遇到右儿子,访问右节点
                        mp[p]++;
                        st.push(p);
                        root=p->right;
                        break;
                    }
                }
            }
        }
        return ans;
    }
};

除了用map记录外,还有一个十分巧妙的方法,如果说我们这次对root进行了访问,那么上次是对谁访问的?,一定是root->right,所以我们可以再访问root的同时对root记录一下,然后下次判断该节点是否可以访问的时候直接判断mark是否等于该节点的右儿子即可。

class Solution {
    vector<int> ans;
public:
    stack<TreeNode*>st;
    vector<int> postorderTraversal(TreeNode* root) {
        mp.clear();
        if(!root) return ans;
        TreeNode* mark=NULL;
        while(root||st.size()){
            if(root){
                st.push(root);
                root=root->left;
            }
            else {
                while(st.size()){
                    TreeNode* p=st.top();
                    st.pop();
                    if(p->right==mark||p->right==NULL){
                        ans.push_back(p->val);
                        mark=p;
                    }
                    else {
                        st.push(p);
                        root=p->right;
                        break;
                    }
                }
            }
        }
        return ans;
    }
};
原文地址:https://www.cnblogs.com/Accepting/p/13752201.html