当前位置: 首页 > wzjs >正文

有做机械工装的网站吗南昌网站seo技术厂家

有做机械工装的网站吗,南昌网站seo技术厂家,上海企业自助建站系统,网站建设管理工作二叉树 知识点 二叉树遍历 前序遍历:先访问根节点,再前序遍历左子树,再前序遍历右子树 中序遍历:先中序遍历左子树,再访问根节点,再中序遍历右子树 后序遍历:先后序遍历左子树,再…

二叉树

知识点

二叉树遍历

前序遍历先访问根节点,再前序遍历左子树,再前序遍历右子树
中序遍历:先中序遍历左子树,再访问根节点,再中序遍历右子树
后序遍历:先后序遍历左子树,再后序遍历右子树,再访问根节点

注意点

  • 以根访问顺序决定是什么遍历
  • 左子树都是优先右子树
递归模板
  • 递归实现二叉树遍历非常简单,不同顺序区别仅在于访问父结点顺序
def preorder_rec(root):if root is None:returnvisit(root)preorder_rec(root.left)preorder_rec(root.right)returndef inorder_rec(root):if root is None:returninorder_rec(root.left)visit(root)inorder_rec(root.right)returndef postorder_rec(root):if root is None:returnpostorder_rec(root.left)postorder_rec(root.right)visit(root)return
前序非递归
  • 本质上是图的DFS的一个特例,因此可以用栈来实现
class Solution:def preorderTraversal(self, root: TreeNode) -> List[int]:preorder = []if root is None:return preorders = [root]while len(s) > 0:node = s.pop()preorder.append(node.val)if node.right is not None:s.append(node.right)if node.left is not None:s.append(node.left)return preorder
中序非递归
class Solution:def inorderTraversal(self, root: TreeNode) -> List[int]:s, inorder = [], []node = rootwhile len(s) > 0 or node is not None:if node is not None:s.append(node)node = node.leftelse:node = s.pop()inorder.append(node.val)node = node.rightreturn inorder
后序非递归
class Solution:def postorderTraversal(self, root: TreeNode) -> List[int]:s, postorder = [], []node, last_visit = root, Nonewhile len(s) > 0 or node is not None:if node is not None:s.append(node)node = node.leftelse:peek = s[-1]if peek.right is not None and last_visit != peek.right:node = peek.rightelse:last_visit = s.pop()# 访问过右节点postorder.append(last_visit.val)return postorder

注意点

  • 核心就是:根节点必须在右节点弹出之后,再弹出

DFS 深度搜索-从下向上(分治法)

class Solution:def preorderTraversal(self, root: TreeNode) -> List[int]:if root is None:return []left_result = self.preorderTraversal(root.left)right_result = self.preorderTraversal(root.right)return [root.val] + left_result + right_result

注意点:

DFS 深度搜索(从上到下) 和分治法区别:前者一般将最终结果通过指针参数传入,后者一般递归返回结果最后合并

BFS 层次遍历
class Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:levels = []if root is None:return levelsbfs = collections.deque([root])while len(bfs) > 0:levels.append([])level_size = len(bfs)for _ in range(level_size):node = bfs.popleft()levels[-1].append(node.val)if node.left is not None:bfs.append(node.left)if node.right is not None:bfs.append(node.right)return levels

分治法应用

先分别处理局部,再合并结果

适用场景

  • 快速排序
  • 归并排序
  • 二叉树相关问题

分治法模板

  • 递归返回条件
  • 分段处理
  • 合并结果

常见题目示例

maximum-depth-of-binary-tree

给定一个二叉树,找出其最大深度。

  • 思路 1:分治法
class Solution:def maxDepth(self, root: TreeNode) -> int:if root is None:return 0return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
  • 思路 2:层序遍历
class Solution:def maxDepth(self, root: TreeNode) -> List[List[int]]:depth = 0if root is None:return depthbfs = collections.deque([root])while len(bfs) > 0:depth += 1level_size = len(bfs)for _ in range(level_size):node = bfs.popleft()if node.left is not None:bfs.append(node.left)if node.right is not None:bfs.append(node.right)return depth

balanced-binary-tree

给定一个二叉树,判断它是否是高度平衡的二叉树。

  • 思路 1:分治法,左边平衡 && 右边平衡 && 左右两边高度 <= 1,
class Solution:def isBalanced(self, root: TreeNode) -> bool:def depth(root):if root is None:return 0, Truedl, bl = depth(root.left)dr, br = depth(root.right)return max(dl, dr) + 1, bl and br and abs(dl - dr) < 2_, out = depth(root)return out
  • 思路 2:使用后序遍历实现分治法的迭代版本
class Solution:def isBalanced(self, root: TreeNode) -> bool:s = [[TreeNode(), -1, -1]]node, last = root, Nonewhile len(s) > 1 or node is not None:if node is not None:s.append([node, -1, -1])node = node.leftif node is None:s[-1][1] = 0else:peek = s[-1][0]if peek.right is not None and last != peek.right:node = peek.rightelse:if peek.right is None:s[-1][2] = 0last, dl, dr = s.pop()if abs(dl - dr) > 1:return Falsed = max(dl, dr) + 1if s[-1][1] == -1:s[-1][1] = delse:s[-1][2] = dreturn True

binary-tree-maximum-path-sum

给定一个非空二叉树,返回其最大路径和。

  • 思路:分治法。最大路径的可能情况:左子树的最大路径,右子树的最大路径,或通过根结点的最大路径。其中通过根结点的最大路径值等于以左子树根结点为端点的最大路径值加以右子树根结点为端点的最大路径值再加上根结点值,这里还要考虑有负值的情况即负值路径需要丢弃不取。
class Solution:def maxPathSum(self, root: TreeNode) -> int:self.maxPath = float('-inf')def largest_path_ends_at(node):if node is None:return float('-inf')e_l = largest_path_ends_at(node.left)e_r = largest_path_ends_at(node.right)self.maxPath = max(self.maxPath, node.val + max(0, e_l) + max(0, e_r), e_l, e_r)return node.val + max(e_l, e_r, 0)largest_path_ends_at(root)return self.maxPath

lowest-common-ancestor-of-a-binary-tree

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

  • 思路:分治法,有左子树的公共祖先或者有右子树的公共祖先,就返回子树的祖先,否则返回根节点
class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if root is None:return Noneif root == p or root == q:return rootleft = self.lowestCommonAncestor(root.left, p, q)right = self.lowestCommonAncestor(root.right, p, q)if left is not None and right is not None:return rootelif left is not None:return leftelif right is not None:return rightelse:return None

BFS 层次应用

binary-tree-zigzag-level-order-traversal

给定一个二叉树,返回其节点值的锯齿形层次遍历。Z 字形遍历

  • 思路:在BFS迭代模板上改用双端队列控制输出顺序
class Solution:def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:levels = []if root is None:return levelss = collections.deque([root])start_from_left = Truewhile len(s) > 0:levels.append([])level_size = len(s)if start_from_left:for _ in range(level_size):node = s.popleft()levels[-1].append(node.val)if node.left is not None:s.append(node.left)if node.right is not None:s.append(node.right)else:for _ in range(level_size):node = s.pop()levels[-1].append(node.val)if node.right is not None:s.appendleft(node.right)if node.left is not None:s.appendleft(node.left)start_from_left = not start_from_leftreturn levels

二叉搜索树应用

validate-binary-search-tree

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

  • 思路 1:中序遍历后检查输出是否有序,缺点是如果不平衡无法提前返回结果, 代码略

  • 思路 2:分治法,一个二叉树为合法的二叉搜索树当且仅当左右子树为合法二叉搜索树且根结点值大于右子树最小值小于左子树最大值。缺点是若不用迭代形式实现则无法提前返回,而迭代实现右比较复杂。

class Solution:def isValidBST(self, root: TreeNode) -> bool:if root is None: return Truedef valid_min_max(node):isValid = Trueif node.left is not None:l_isValid, l_min, l_max = valid_min_max(node.left)isValid = isValid and node.val > l_maxelse:l_isValid, l_min = True, node.valif node.right is not None:r_isValid, r_min, r_max = valid_min_max(node.right)isValid = isValid and node.val < r_minelse:r_isValid, r_max = True, node.valreturn l_isValid and r_isValid and isValid, l_min, r_maxreturn valid_min_max(root)[0]
  • 思路 3:利用二叉搜索树的性质,根结点为左子树的右边界,右子树的左边界,使用先序遍历自顶向下更新左右子树的边界并检查是否合法,迭代版本实现简单且可以提前返回结果。
class Solution:def isValidBST(self, root: TreeNode) -> bool:if root is None:return Trues = [(root, float('-inf'), float('inf'))]while len(s) > 0:node, low, up = s.pop()if node.left is not None:if node.left.val <= low or node.left.val >= node.val:return Falses.append((node.left, low, node.val))if node.right is not None:if node.right.val <= node.val or node.right.val >= up:return Falses.append((node.right, node.val, up))return True
insert-into-a-binary-search-tree

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。

  • 思路:如果只是为了完成任务则找到最后一个叶子节点满足插入条件即可。但此题深挖可以涉及到如何插入并维持平衡二叉搜索树的问题,并不适合初学者。
class Solution:def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:if root is None:return TreeNode(val)node = rootwhile True:if val > node.val:if node.right is None:node.right = TreeNode(val)return rootelse:node = node.rightelse:if node.left is None:node.left = TreeNode(val)return rootelse:node = node.left

总结

  • 掌握二叉树递归与非递归遍历
  • 理解 DFS 前序遍历与分治法
  • 理解 BFS 层次遍历

练习

  • maximum-depth-of-binary-tree
  • balanced-binary-tree
  • binary-tree-maximum-path-sum
  • lowest-common-ancestor-of-a-binary-tree
  • binary-tree-level-order-traversal
  • binary-tree-level-order-traversal-ii
  • binary-tree-zigzag-level-order-traversal
  • validate-binary-search-tree
  • insert-into-a-binary-search-tree

文章转载自:

http://QzJBkdu3.sfnjr.cn
http://ZojpNhUZ.sfnjr.cn
http://qVxoQqjJ.sfnjr.cn
http://BRvYuJqt.sfnjr.cn
http://kz59pDSt.sfnjr.cn
http://rSUnxMNh.sfnjr.cn
http://e6eLal58.sfnjr.cn
http://VMkSDUUX.sfnjr.cn
http://1NQhvNxF.sfnjr.cn
http://z4LCrP8J.sfnjr.cn
http://hgdqprcH.sfnjr.cn
http://ulu9kbGl.sfnjr.cn
http://SaNWY7DI.sfnjr.cn
http://kzRqjFnF.sfnjr.cn
http://q3ZPVJVx.sfnjr.cn
http://m3EzdHcM.sfnjr.cn
http://k8ga1Nrb.sfnjr.cn
http://lc61soLi.sfnjr.cn
http://O260W0HZ.sfnjr.cn
http://1Y4Ehg56.sfnjr.cn
http://NEtpJaKu.sfnjr.cn
http://ivVz4Lgr.sfnjr.cn
http://Ypv3v9ia.sfnjr.cn
http://XEG9JYvB.sfnjr.cn
http://38qnbqJj.sfnjr.cn
http://XbBwVoh9.sfnjr.cn
http://Q0F2I9Jq.sfnjr.cn
http://Lkw6uHhP.sfnjr.cn
http://1Jdlb88X.sfnjr.cn
http://JVipmGrJ.sfnjr.cn
http://www.dtcms.com/wzjs/617555.html

相关文章:

  • 建站需要什么软件柳州正规网站制作公司
  • 企业法律平台网站建设方案学网站开发难吗
  • 在唐山做网站多少钱济南旅游网页设计
  • 手机网站商城源码网站如何做的看起来高大上
  • 免费域名申请网站wordpress随机文章列表
  • 自己搭建视频播放网站wordpress 子分类
  • 网站建设公司 盐城市竞价托管推广
  • 个人做网站需要什么条件滨州网站seo服务
  • 网站开发和ipv6带做网站
  • 怎么看一个网站做外链苏州建设网站首页
  • 天河建设网站平台wordpress评论字段
  • 国家住房和城乡建设局网站泉州pc网站开发
  • 黑彩网站自己可以做么前端工作6年一般拿多少工资
  • 制作商品网站邯郸网络科技有限公司哪家好
  • 手机网站 免费公司做两个网站有影响吗
  • 室内设计培训班学费一般多少搜索关键词优化服务
  • 专业旅游网站开发系统平面设计课程标准
  • 国外 网站开发框架微信小程序是什么
  • 商城推广 网站建设做电影网站被告版权
  • 威县网站建设代理价格宁波网站建设设计制作公司
  • 淘客网站模板湖北网站制作公司
  • 网站开发工程师怎么样wordpress博客 免费
  • 网站备案密码查询招聘网站设计师要求
  • 做网站的公司挣钱吗wordpress 调用所有
  • 烟台建设协会网站局域网建网站的详细步骤
  • 网站建设需要哪些岗位深圳注册公司需要哪些材料和流程
  • 怎么用切片和dw做网站绵阳建设局网站
  • 代理备案 网站 安全吗营销型企业网站源码
  • 做一个购物商城网站多少钱大学电子商务网站建设方案
  • 建设银行网址网站优化包括对什么优化