Binary Tree Postorder Traversal--leetcode难题讲解系列

时间:2021-08-08 03:05:11

https://leetcode.com/problems/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?

 

后续遍历二叉树,要求不使用递归。

很明显需要使用栈来进行迭代。后续遍历是依序访问左子树,右子树,根节点。我们的入口是根节点,那么我们的栈应该先保存根,然后右子树,再保存左子树。

 

分开来看,根的左孩子有可能是根而不是叶子结点,我们需要一路向下保存根节点,直到遇到叶子结点,才能保证根最先保存。

 

怎么样保证右子树比左子树先保存呢?事实上我们访问的顺序是先左后右。现在我们只需要保证右子树比根节点优先输出(后入栈),而左子树已全部出栈就可以。怎么判断什么时候入栈(第一次遇到根(左孩子),第一次遇到右孩子),什么时候出栈(第二次遇到右孩子,第二次遇到根(左孩子))?我们需要有一个pre变量来记录之前遇到的最后一个节点。如果pre和当前节点的右孩子值相等,那么我们是第二次遇到根,此时右孩子早已访问,直接根出栈。否则,我们应访访问当前节点的右孩子(入栈)。

 

// C++  CODE:
class
Solution {public:
vector
<int> postorderTraversal(TreeNode* root) {
stack
<TreeNode*> s;
vector
<int> result;
while(root){
s.push(root);
root
= root->left;
}
while(!s.empty()){
TreeNode
* tmp = s.top();
if(tmp->right){
if(result.empty()||tmp->right->val !=result[result.size()-1]){
TreeNode
* tmproot = tmp->right;
while(tmproot){
s.push(tmproot);
tmproot
= tmproot->left;
}
}
else{
result.push_back(tmp
->val);
s.pop();
}
}
else{
result.push_back(tmp
->val);
s.pop();
}
}
return result;
}
};

 

# PYTHON CODE:
class
Solution: # @param root, a tree node
# @return a list of integers
def postorderTraversal(self, root):
stack, cur, pre, res
= [], root, None, []
while cur or stack:
if cur:
stack.append(cur)
cur
= cur.left
else:
if stack[-1].right in (None, pre):
res.append(stack[
-1].val)
pre
= stack.pop()
else:
cur
= stack[-1].right
return res