关于Tree相关问题总结---重点

  1. dfs 包括:
    preorder(copy tree), inorder (non-descending order for BST), postorder traversal (delete tree) 的recursive方法还有iterative的方法
    http://www.geeksforgeeks.org/618/
    http://www.cnblogs.com/zuoyuan/p/3720846.html
    注意比较三种code,pre order 和inorder仅仅是res赋值的位置不一样,postorder

    • pre order 不停地遍历左子树,并且每次遍历都给res赋值,都push到stack中。一直到最左的node。然后开始pop到右子树节点,针对此右子树,再找最左node。。。一直到stack和root都为空

    • note 这三种遍历方式都是用stack存储scan的路径。先找到最左node,然后backtrace。。。。也为我们提供了找某一点path的方法,stack存储的就是stack.peek的path。

class Solution(object):

    def iterative_preorder(self, root, res):

        stack = []
        while stack or root:
            if root:#一直搜left subtree until None. 
                res.append(root.val)#pre order是在这里加入到res中
                stack.append(root)
                root = root.left
            else:#已经搜到了最left的subtree,这个点得left subtree是None了,所以这里要pop出上一个element,然后求其right subtree
                root = stack.pop()
                root = root.right
        return res

    def preorder(self, root, res):

        if root:
            res.append(root.val)
            self.preorder(root.left, res)
            self.preorder(root.right, res)

    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        #self.preorder(root,res)
        self.iterative_preorder(root,res)
        return res
  • In order
    跟pre order类似,也是不停地找最左子树,然后push到stack。只是给res赋值发生在找到最左子树,pop之后。
class Solution(object):

    def iterative_inorder(self, root, res):

        stack = []
        while stack or root:
            if root:#一直搜left subtree until None. 
                stack.append(root)
                root = root.left
            else:#已经搜到了最left的subtree,这个点得left subtree是None了,所以这里要pop出上一个element,然后求其right subtree
                root = stack.pop()
                res.append(root.val)#compared with pre order, in order just move the res part here
                root = root.right
        return res

    def inorder(self, root, res):

        if root:
            self.inorder(root.left, res)
            res.append(root.val)
            self.inorder(root.right, res)

    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        #self.inorder(root, res)
        self.iterative_inorder(root,res)
        return res

-Post order
http://www.cnblogs.com/zuoyuan/p/3720846.html 解释的很好。stack中先存右子树再存左子树。。。

good explaination http://stackoverflow.com/questions/1294701/post-order-traversal-of-binary-tree-without-recursion
We would push the root node to the stack first. While the stack is not empty, we keep pushing the left child of the node from top of stack. If the left child does not exist, we push its right child. If it’s a leaf node, we process the node and pop it off the stack.

We also use a variable to keep track of a previously-traversed node. The purpose is to determine if the traversal is descending/ascending the tree, and we can also know if it ascend from the left/right.

If we ascend the tree from the left, we wouldn’t want to push its left child again to the stack and should continue ascend down the tree if its right child exists. If we ascend the tree from the right, we should process it and pop it off the stack.

We would process the node and pop it off the stack in these 3 cases:

The node is a leaf node (no children)
We just traverse up the tree from the left and no right child exist.
We just traverse up the tree from the right.

my code:

class Solution(object):

    def iterative_postorder(self, root, list):

        stack = []
        lastVisit = None
        while stack or root:
            if root:
                stack.append(root)
                root = root.left
            else:
                peek = stack[-1]#got the most left subtree node, see wether it has right subtree otherwise go to scan its parent
                if peek.right and lastVisit != peek.right:# condition 3
                    root = peek.right
                else:
                    list.append(peek.val)
                    lastVisit = stack.pop()
                    root = None #一直从stack里面拿element,直到这个element有right subtree

    def iterative_postorder2(self, root, list):
        stack = []
        pre = None
        if root:
            #print root.val
            stack.append(root)
            while stack:
                curr = stack[len(stack) - 1]
                c1 = (curr.left == None and curr.right == None) # if current node is leaf node
                c2 = (pre == curr.left and curr.right == None) # if current node doesn't have right subtree and last visit node is left subtree
                c3 = (pre == curr.right and pre != None)# if last visit is right subtree and right subtree is not None
                if c1 or c2 or c3:
                    list.append(curr.val)
                    stack.pop()
                    pre = curr
                else:
                    if curr.right: stack.append(curr.right)
                    if curr.left: stack.append(curr.left)
        return list

    def postorder(self, root, res):
        if root:
            self.postorder(root.left, res)
            self.postorder(root.right, res)
            res.append(root.val)




    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        #self.postorder(root, res)
        self.iterative_postorder2(root, res)
        return res

这里的dfs其实是travesal版本,用来遍历所有tree node。而dfs可以用来backtracking,在排列组合,搜索解空间问题上常用。

参考排列和组合问题。 以及自己的算法notes中的回溯算法

  1. bfs的 level order traversal.

  2. 枚举所有从root到leaf的path

  3. 给定一个node,找一条从root到它的path

使用post order. return stack

    def findPath(self, root, target):
        stack = []
        lastVisit = None
        while stack or root:
            if root:
                stack.append(root)
                root = root.left
            else:
                peek = stack[-1]
                if peek.right and lastVisit != peek.right:
                    root = peek.right
                else:
                    if peek == target:
                        return stack
                    lastVisit = stack.pop()
                    root = None
        return stack
  1. 常用到stack和queue。

    stack可以就用list, stack = [], stack.append()就是push,stack.pop()就是pop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值