二叉树非递归后序遍历

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

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

能够看到,对于root,咱们老是先访问root的left儿子,right儿子,而后再访问root,也就是说,咱们第三次看到root时候再对它进行访问。spa

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

记录某个节点出现的次数,咱们能够借用map。blog

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是否等于该节点的右儿子便可。io

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;
    }
};