68. 二叉树的后序遍历
题目
给出一棵二叉树,返回其节点值的后序遍历。
样例
给出一棵二叉树 {1,#,2,3}
,
1
\
2
/
3
返回 [3,2,1]
挑战
你能使用非递归实现么?
题解
我想使用非递归做法,知道是用stack,但具体怎么操作呢?首先我们的想法是后续遍历,一开始要找到最左下的节点,然后进行左右中这种操作。好,给出一个root,那我们temp=root开始操作。
while temp != None: stack.append(temp) temp = temp.left
此时我们已经去到左下角,那当然我们要开始回溯,我们就用样例来做例子,此时在1身上,因为1没有左子树,就是属于最左了。此时我们应该需要找右边的节点,但是搜索右边的节点的时候,我们会访问到父节点,此时我们先不能读取他的值,否则就顺序错乱了。
我们可以做一个标记的变量,标记这个节点是从哪个节点回溯回来的,如果是右边节点,则可以读取当前的值,否则是左边回来的话,就要先放回到stack里,等右边的树结束了才到自己。
def postorderTraversal(self, root): stack = [] lst = [] p = None temp = root while temp != None or len(stack) > 0: while temp != None and getattr(temp.left, "mark", 0)==0: #找最左节点 stack.append(temp) temp = temp.left if temp == None and len(stack) >0: #回溯,判定从左还是从右回溯 temp = stack.pop(-1) if p == temp.right: temp.mark = 1 if getattr(temp, "mark", 0)==1: #打印 lst.append(temp.val) if getattr(temp, "mark", 0) == 0: #如果是第一次访问,则放回入stack里,并做标记 stack.append(temp) temp.mark = 1 if temp.right and getattr(temp.right, "mark", 0) == 0: #往右走 temp = temp.right else: temp = None p = temp #记录上次搜索的节点,供判定左右节点使用 return lst