题目描述
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?
算法思路
1)设置p节点,表示已经刚才出栈的元素
2)如果当前节点的左节点或右节点为刚才出栈的节点,说明此节点也可以进行出栈
3)如果当前节点不可以出栈,则将它的右节点和左节点依次入栈
算法实现
class TreeNode():
def __init__(self,x):
self.val=x
self.left=None
self.right=None
class Solution:
def postorderTraversal(self,root):
if root==None:
return
res=[]
stack=[root]
p=root #标识元素,用来判断节点是否“刚才”已经遍历过
while stack:
top=stack[-1]
#该出栈元素——子节点已经遍历过了 或 为叶子节点
if top.left==p or top.right==p or (top.left==None and top.right==None):
p=stack.pop()
res.append(p.val)
#该入栈元素——先入栈右节点,在入栈当前节点左节点,是并列的
else:
if top.right:
stack.append(top.right)
if top.left:
stack.append(top.left)
return res
#测试
test=Solution()
n1=TreeNode(1)
n2=TreeNode(2)
n3=TreeNode(3)
n4=TreeNode(4)
n5=TreeNode(5)
n6=TreeNode(6)
n7=TreeNode(7)
n1.left=n2
n1.right=n3
n2.left=n4
n3.left=n5
n3.right=n6
n6.right=n7
"""
1
/ \
2 3
/ /\
4 5 6
\
7
"""
print(test.postorderTraversal(n1))
#[4, 2, 5, 7, 6, 3, 1]
小结
后序遍历的输出条件为:
当前节点为叶子节点,或当前节点左节点和右节点已经输出过了
基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。 如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。