二叉树的前中后遍历,层次遍历,树的递归问题(递归与迭代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 = 22, 5 / \ 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