[leetcode] 145. Binary Tree Postorder Traversal

Given a binary tree, return the postorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

这道题是后序遍历二叉树,题目难度为Hard。二叉树遍历是数据结构中的基本问题,觉得太low的同学可以跳过。


递归版本比较简单,不再详细说明,具体代码:

class Solution {
    void getPostData(TreeNode* root, vector<int>& ret) {
        if(!root) return;
        if(root->left) getPostData(root->left, ret);
        if(root->right) getPostData(root->right, ret);
        ret.push_back(root->val);
    }
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ret;
        getPostData(root, ret);
        return ret;
    }
};

下面介绍非递归的方法,后序遍历二叉树是一种深度优先的遍历方法,不用递归的话就需要用栈来存储遍历路径上的节点。从根节点开始,一直向左遍历,依次将经过的节点进栈,直到某节点(记为p)的左子树为空,接下来就可以去遍历p的右子树了,如果它的右子树不空且没有遍历过,跳到它的右子树继续上述循环,否则说明p的右子树已经遍历完成,就可以将p出栈进行遍历了,这样循环直至栈空即完成了二叉树的后序遍历。如何判断p的右子树有没有遍历过呢?这里需要记录上一个后续遍历完毕的节点(记为q),即它的左右子树和它自己都已经遍历过了,如果p的右子树为q或为空,表明p的左右子树均已经遍历完毕,可以遍历p自己了,此时将堆栈出栈,遍历p并将q更新为p,因为p已经后序遍历完毕,这样通过q即可判断p的右子树是否已经遍历过。具体代码:
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ret;
        stack<TreeNode*> stk;
        TreeNode* p = root;
        TreeNode* q = NULL;
        
        while(p || !stk.empty()) {
            while(p) {
                stk.push(p);
                p = p->left;
            }
            p = stk.top();
            if(p->right == NULL || p->right == q) {
                q = p;
                stk.pop();
                ret.push_back(p->val);
                p = NULL;
            }
            else {
                p = p->right;
            }
        }
        
        return ret;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值