[leetcode]Binary Tree Postorder Traversal

后序遍历非递归是三种里面最难的,难处在于要判断是否左右子树都已经访问完毕。
有两种方式,一种是用0和1记录当前节点是从左节点返回还是从右节点返回。空间O(n)http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810055.html
另一种是维基百科上的,判断前驱节点是父亲还是左儿子实现的,这种方式稍微省点空间(其实也是O(n))。http://en.wikipedia.org/wiki/Postorder
思路如下:
1.栈记录的是节点的访问次序;
2.每个节点进栈出栈一次;
3.出栈的时候就打印(visit),但只有在左右儿子都visit后才出栈;
4.while循环中每次都push一个入栈,如果不入栈就打印(左右儿子都visit过);
5.previous记录上一个访问的节点,current是peek一下当前栈顶,当前访问的节点,如图可见,每个节点访问两次;
6.上一个是父亲,则push左儿子(或左儿子空就push右儿子);
7.上一个是左儿子,就push右儿子;
8.上一个不是父亲也不是左儿子,那上一个就是右儿子(或自己,右儿子为空时),打印;(这几步可以参见下图)

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> ans;
        if (root == NULL) return ans;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* prev = NULL;
        while (!st.empty()) {
            TreeNode* current = st.top();
            if (prev == NULL || prev->left == current || prev->right == current) {
                if (current->left != NULL) {
                    st.push(current->left);
                }
                else if (current->right != NULL) {
                    st.push(current->right);
                }
            }
            else if (prev == current->left) {
                if (current->right != NULL) {
                    st.push(current->right);
                }
            }
            else {
                ans.push_back(current->val);
                st.pop();
            }
            prev = current;
        }
        return ans;
    }
};

中序:http://www.cnblogs.com/lautsie/p/3261119.html

 先序:http://www.cnblogs.com/lautsie/p/3418670.html

第二刷使用计数的方法,这个的好处在于,如果是多叉树,更方便;二来,写法的框架和先序什么的比较一致;三来简洁:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> vec;
        stack<pair<TreeNode*, int>> stk;
        TreeNode* node = root;
        while (not stk.empty() || node != NULL) {
            if (node != NULL) {
                stk.push(make_pair(node, 1));
                node = node->left;
            } else {
                if (stk.top().second == 1) {
                    stk.top().second = 2;
                    node = stk.top().first->right;
                } else {
                    vec.push_back(stk.top().first->val);
                    stk.pop();
                    node = NULL;
                }
            }
        }
        return vec;
    }
};

  

posted @ 2013-11-11 22:46  阿牧遥  阅读(261)  评论(0编辑  收藏  举报