zoukankan      html  css  js  c++  java
  • 二叉树的前中后遍历,层次遍历,树的递归问题(递归与迭代python)

    树的遍历原理:
    https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/
    
    二叉树的前序遍历:
    
    
    
    输入: [1,null,2,3]  
       1
        
         2
        /
       3 
    
    输出: [1,2,3]
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def preorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            if root==None:
                return []
    #         思路:前序遍历的顺序为:中左右,迭代算法思路:使用栈的思想,从根节点开始以此使用res添加根节点值,stack添加右节点,curr=左节点,如果左节点为None,则获取其上一个右节点(一直输出跟节点,添加其右节点,遍历左节点,右节点的输出顺序为从下往上)
            stack=[]
            curr=root
            res=[]
            while curr or stack:
                if curr:
                    res.append(curr.val)
                    stack.append(curr.right)
                    curr=curr.left
                else:
                    curr=stack.pop()
            return res
    #迭代
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def preorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            if root==None:
                return []
        
            res=[]
            self.recursion_(root,res)
            return res
        
    #     思路:递归,中左右,每一步进行添加root.val,
        def recursion_(self,root,res):
            if root==None:
                return False
            res.append(root.val)
            if root.left:
                self.recursion_(root.left,res)
            if root.right:
                self.recursion_(root.right,res)
    中序遍历二叉树:
    输入: [1,null,2,3]
       1
        
         2
        /
       3
    
    输出: [1,3,2]
    #迭代
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def inorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            # 左中右
            stack=[]  #添加根节点
            curr=root
            res=[]
            while curr or stack:
                if curr:
                    stack.append(curr)
                    curr=curr.left
                else:
                    curr=stack.pop()
                    res.append(curr.val)
                    curr=curr.right
            return res
    #递归
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def inorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            self.resucri_(root,res)
            return res
        def resucri_(self,root,res):
            if root==None:
                return False
            if root.left:
                self.resucri_(root.left,res)
            res.append(root.val)
            if root.right:
                self.resucri_(root.right,res)
    二叉树的后序遍历
    输入: [1,null,2,3]  
       1
        
         2
        /
       3 
    
    输出: [3,2,1]
    #迭代
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def postorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            #思路:后序遍历方式为:左右中,将其进行反转 中右左,那么我们可以实现一个中右左,其原理与前序遍历一样
            stack=[]
            curr=root
            res=[]
            while curr or stack:
                if curr:
                    res.append(curr.val)
                    stack.append(curr.left)
                    curr=curr.right
                else:
                    curr=stack.pop()
            return res[::-1]
    #递归
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def postorderTraversal(self, root):
            """
            :type root: TreeNode
            :rtype: List[int]
            """
            res=[]
            self.recursion_(root,res)
            return res
        def recursion_(self,root,res):
            if root==None:
                return False
            if root.left:
                self.recursion_(root.left,res)
            if root.right:
                self.recursion_(root.right,res)
            res.append(root.val)
    二叉树的层次遍历
    层序遍历就是逐层遍历树结构。
    
    广度优先搜索是一种广泛运用在树或图这类数据结构中,遍历或搜索的算法。 该算法从一个根节点开始,首先访问节点本身。 然后遍历它的相邻节点,其次遍历它的二级邻节点、三级邻节点,以此类推。
    
    当我们在树中进行广度优先搜索时,我们访问的节点的顺序是按照层序遍历顺序的。通常,我们使用一个叫做队列的数据结构来帮助我们做广度优先搜索。
    
    图解介绍:
    https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/8/
    
    给定一个二叉树:
        3
       / 
      9  20
        /  
       15   7
    输出:
    [
      [3],
      [9,20],
      [15,7]
    ]
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def levelOrder(self, root):
            """
            :type root: TreeNode
            :rtype: List[List[int]]
            """
            #队列实现(BFS),使用queue记录二叉树每一层的节点,next_queue记录queue下的节点,i记录层数,res记录节点(先进后出)
            if root==None:
                return []
            queue=[root]
            next_queue=[]
            res=[]
            i=-1
            while queue or next_queue:
                i+=1
                res.append([])
                while queue:
                    curr=queue.pop(0)
                    if curr!=None:
                        res[i].append(curr.val)
                        if curr.left:
                            next_queue.append(curr.left)
                        if curr.right:
                            next_queue.append(curr.right)
                queue=next_queue
                next_queue=[]
            return res
    运用递归解决问题:
    https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/3/solve-problems-recursively/11/#_2
    当遇到树问题时,请先思考一下两个问题:
    
    你能确定一些参数,从该节点自身解决出发寻找答案吗?
    你可以使用这些参数和节点本身的值来决定什么应该是传递给它子节点的参数吗?
    如果答案都是肯定的,那么请尝试使用 “自顶向下” 的递归来解决此问题。
    
    对于树中的任意一个节点,如果你知道它子节点的答案,你能计算出该节点的答案吗? 如果答案是肯定的,那么 “自底向上” 的递归可能是一个不错的解决方法。
    二叉树的最大深度
    给定一个二叉树,找出其最大深度。
    
    二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
    
    说明: 叶子节点是指没有子节点的节点。
    
    示例:
    给定二叉树 [3,9,20,null,null,15,7],
        3
       / 
      9  20
        /  
       15   7
    返回它的最大深度 3 。
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def maxDepth(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
    #         采用自顶向下
            self.res=0
    #     根节点深度默认为1
            self.recursion(root,1)
            return self.res
        def recursion(self,root,depth):
            if root==None:
                return False
            #确定为叶子结点,则进行判断最大深度
            if root.left==None and root.right==None:
                self.res=max(self.res,depth)
            if root.left:
                self.recursion(root.left,depth+1)
            if root.right:
                self.recursion(root.right,depth+1)    
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def maxDepth(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
    #         采用自底向上,由叶子结点的深度为1,往上走
            return self.recursion(root)
        def recursion(self,root):
            if root==None:
                return 0
            left_=self.recursion(root.left)
            right_=self.recursion(root.right)
            return max(left_,right_)+1
            
    对称二叉树
    给定一个二叉树,检查它是否是镜像对称的。
    
    例如,二叉树 [1,2,2,3,4,4,3] 是对称的
    给定一个二叉树,检查它是否是镜像对称的。
    
    例如,二叉树 [1,2,2,3,4,4,3] 是对称的
    #递归
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def isSymmetric(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
    #     思路:采用自顶向下的方式进行递归.其实是判断左右子树是否相等, 将树进行划分为两颗子树
            if root == None:
                return True
            return self.recursion(root.left,root.right)
        def recursion(self,left,right):
            if left == None and right == None:
                return True
            if left == None or right == None:
                return False
            if left.val != right.val:
                return False
            else:
                return self.recursion(left.left,right.right) and self.recursion(right.left,left.right)
    #迭代
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def isSymmetric(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
    #       思路:使用迭代,每一次遍历出一层元素,对该元素层取反,相等则继续,不相等返回False
            import copy
            if root == None:
                return True
            stack=[root]
            next_stack=[]
            while stack or next_stack:
                node=[]
                while stack:
                    root=stack.pop()
                    if root.left:
                        next_stack.append(root.left)
                        node.append(root.left.val)
                    else:
                        node.append(False)
                    if root.right:
                        next_stack.append(root.right)
                        node.append(root.right.val)
                    else:
                        node.append(False)
                rever_node=copy.copy(node)
                rever_node.reverse()
                if rever_node!=node:
                    return False
                stack=next_stack
                next_stack=[]
            return True
    路径总和
    给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
    
    说明: 叶子节点是指没有子节点的节点。
    
    示例: 
    给定如下二叉树,以及目标和 sum = 225
                 / 
                4   8
               /   / 
              11  13  4
             /        
            7    2      1
    返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):  
        def hasPathSum(self, root, sum):
            """
            :type root: TreeNode
            :type sum: int
            :rtype: bool
            递归
            """
    #       思路:采用自顶向下的递归方式,当到达左右节点都为None的时候,进行判断
            self.flag=False
            return self.rescursion(root,0,sum)
        def rescursion(self,root,now,want):
            if root==None:
                return False
            now+=root.val
            #确定为叶子节点
            if root.left == None and root.right == None:
                #判断和是否和目标和相等
                if now==want:
                    self.flag=True
                    #这里的return 有两层意义,第一层:当树深只有一层时,其返回True,第二层,起到为中断迭代作用(即返回上一个迭代点)
                    return True
            self.rescursion(root.left,now,want)
            self.rescursion(root.right,now,want)
            return self.flag
  • 相关阅读:
    1046 Shortest Distance (20 分)(模拟)
    1004. Counting Leaves (30)PAT甲级真题(bfs,dfs,树的遍历,层序遍历)
    1041 Be Unique (20 分)(hash散列)
    1036 Boys vs Girls (25 分)(查找元素)
    1035 Password (20 分)(字符串处理)
    1044 Shopping in Mars (25 分)(二分查找)
    onenote使用小Tip总结^_^(不断更新中...)
    1048 Find Coins (25 分)(hash)
    三个故事
    领导者的举止
  • 原文地址:https://www.cnblogs.com/liuyicai/p/10156455.html
Copyright © 2011-2022 走看看