二叉樹非遞歸後序遍歷

先來看一下遞歸版的後序遍歷是怎麼寫的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;
    }
};
相關文章
相關標籤/搜索