题目大意

二叉树后序遍历
挑战:迭代解题

解题思路

递归简单

代码

递归

class Solution(object):

    def _postorderTraversal(self, root, result):
        if root:
            self._postorderTraversal(root.left, result)
            self._postorderTraversal(root.right, result)
            result.append(root.val)
    def postorderTraversal(self, root):
        """ :type root: TreeNode :rtype: List[int] """
        if root == None:
            return []
        result = []
        self._postorderTraversal(root, result)
        return result

迭代

将数组输出为右子树-左子树-根节点。最后,再将数组倒序输出,形成后序遍历。这样代码并不用很繁琐,也能做完迭代。(前序遍历是左子树-右子树-根节点)

代码根据前序遍历完美修改:

class Solution(object):
    def postorderTraversal(self, root):
        """ :type root: TreeNode :rtype: List[int] """
        if root is None:
            return []
        ret = []
        stack = [root]
        while stack:
            node = stack.pop()
            if node:
                ret.append(node.val)
                if node.left:
                    stack.append(node.left)
                if node.right:
                    stack.append(node.right)
        return ret[::-1]

补充思路

         1

      /  \ 
     2    3

          / \ 
       4  5

使用一个栈。分几个步骤:

一,将根节点入栈,并将根节点的孩子入栈,入栈顺序为:先入右孩子,再入左孩子,顺序不能错。因为这样在弹栈时的顺序就是后序遍历的顺序了。如果左孩子还有左孩子或者右孩子,那么继续按先右后左的顺序入栈。那么上面这棵树开始的入栈顺序是:1,3,2。由于2不存在左右孩子,停止入栈。

二,由于2没有左右孩子,遍历2并将2弹出,同时使用prev记录下2这个节点。

三,2出栈后,栈为{1,3},此时3在栈顶,由于3存在左右孩子,按顺序入栈,此时栈为{1,3,5,4}。

四,将4和5遍历并出栈,此时prev指向5,栈为{1,3}。prev的作用是什么呢?用来判断prev是否为栈顶元素的孩子,如果是,则说明子树的孩子已经遍历完成,需要遍历树根了。以上树为例:4和5出栈后,prev指向5,而5是栈顶元素3的孩子,说明孩子已经遍历完毕,则遍历3然后弹出3即可,即完成了子树{3,4,5}的后序遍历。

五,此时栈为{1},为树根,而左右子树都遍历完了,最后遍历树根并弹出即可。

总结