不止于刷题:用Python实战‘二叉树侧影’,理解DFS/BFS在视图问题中的应用

张开发
2026/4/20 11:13:58 15 分钟阅读

分享文章

不止于刷题:用Python实战‘二叉树侧影’,理解DFS/BFS在视图问题中的应用
不止于刷题用Python实战‘二叉树侧影’理解DFS/BFS在视图问题中的应用在算法学习与工程实践中二叉树视图问题是一个经典且实用的场景。无论是准备技术面试还是开发实际应用理解如何高效获取二叉树的左右视图都至关重要。本文将带你用Python从零开始不仅解决这个问题更深入探讨DFS与BFS两种策略的差异以及如何将这些代码模块化为可重用的工具函数。1. 二叉树基础与Python实现二叉树是一种每个节点最多有两个子节点的树结构在计算机科学中应用广泛。与C等语言不同Python没有内置的树结构我们需要用类来定义节点class TreeNode: def __init__(self, val0, leftNone, rightNone): self.val val self.left left self.right right1.1 从中序和后序遍历构建二叉树给定中序和后序遍历序列我们可以递归地构建原始二叉树。这是解决视图问题的第一步def build_tree(inorder, postorder): if not inorder or not postorder: return None root_val postorder[-1] root TreeNode(root_val) idx inorder.index(root_val) root.left build_tree(inorder[:idx], postorder[:idx]) root.right build_tree(inorder[idx1:], postorder[idx:-1]) return root这个递归过程的关键点在于后序序列的最后一个元素总是当前子树的根节点在中序序列中找到根节点位置左侧是左子树右侧是右子树递归处理左右子树2. 深度优先搜索(DFS)实现视图提取DFS是一种沿着树的深度遍历节点的算法。对于视图问题我们可以通过记录每层第一个或最后一个访问的节点来实现。2.1 递归DFS实现右视图def right_view_dfs(root): result [] def dfs(node, level): if not node: return if level len(result): result.append(node.val) dfs(node.right, level 1) dfs(node.left, level 1) dfs(root, 0) return result2.2 递归DFS实现左视图def left_view_dfs(root): result [] def dfs(node, level): if not node: return if level len(result): result.append(node.val) dfs(node.left, level 1) dfs(node.right, level 1) dfs(root, 0) return resultDFS方法的特点时间复杂度O(n)空间复杂度O(h)h为树高递归实现简洁但可能面临栈溢出风险适合深度优先的场景如路径相关问题3. 广度优先搜索(BFS)实现视图提取BFS按层次遍历树更适合处理视图问题因为视图本质上就是每层的特定节点。3.1 队列实现BFS视图from collections import deque def right_view_bfs(root): if not root: return [] result [] queue deque([root]) while queue: level_size len(queue) for i in range(level_size): node queue.popleft() if i level_size - 1: # 每层最后一个节点 result.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return result def left_view_bfs(root): if not root: return [] result [] queue deque([root]) while queue: level_size len(queue) for i in range(level_size): node queue.popleft() if i 0: # 每层第一个节点 result.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return resultBFS方法的特点时间复杂度O(n)空间复杂度O(w)w为树的最大宽度迭代实现无栈溢出风险更适合层次相关的问题如视图、层序遍历等4. 算法对比与工程实践4.1 DFS与BFS性能对比特性DFS递归实现BFS迭代实现时间复杂度O(n)O(n)空间复杂度O(h)O(w)适用场景深度优先问题层次相关问题实现难度简单中等栈溢出风险有无4.2 代码模块化与复用在实际工程中我们可以将这些功能封装为二叉树工具类class BinaryTreeUtils: staticmethod def build_from_in_post(inorder, postorder): # 实现前面介绍的建树方法 pass staticmethod def right_view(root, methodbfs): if method bfs: return right_view_bfs(root) else: return right_view_dfs(root) staticmethod def left_view(root, methodbfs): if method bfs: return left_view_bfs(root) else: return left_view_dfs(root)这样封装的好处统一接口便于团队使用支持多种实现方式可根据场景选择易于扩展新功能4.3 实际应用中的优化技巧在处理大规模树结构时可以考虑以下优化迭代DFS用栈代替递归避免栈溢出def right_view_dfs_iterative(root): if not root: return [] result [] stack [(root, 0)] while stack: node, level stack.pop() if level len(result): result.append(node.val) # 注意压栈顺序先左后右因为我们要先处理右子树 if node.left: stack.append((node.left, level 1)) if node.right: stack.append((node.right, level 1)) return result提前终止在某些场景下可能不需要遍历整棵树并行处理对于非常大的树可以考虑并行处理不同子树5. 扩展应用与相关问题掌握了二叉树视图问题的解决方法后可以进一步探索以下相关问题顶部视图和底部视图需要使用水平距离(HD)概念边界遍历包括左边界、叶节点和右边界之字形遍历交替改变遍历方向垂直遍历按列输出节点例如顶部视图的实现def top_view(root): if not root: return [] hd_dict {} queue deque([(root, 0)]) while queue: node, hd queue.popleft() if hd not in hd_dict: hd_dict[hd] node.val if node.left: queue.append((node.left, hd - 1)) if node.right: queue.append((node.right, hd 1)) return [hd_dict[hd] for hd in sorted(hd_dict)]在实际项目中我曾遇到需要可视化二叉树结构的需求。通过结合视图算法和图形库我们能够生成更直观的树形结构展示大大提升了调试效率。特别是在处理复杂决策树时能够快速查看特定视角的节点分布对理解模型行为非常有帮助。

更多文章