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

 

posted on 2018-03-26 21:09  usp10  阅读(118)  评论(0编辑  收藏  举报

导航