树的遍历方法汇总:GitHub_Trending/le/LeetCode-Book前中后序详解

树的遍历方法汇总:GitHub_Trending/le/LeetCode-Book前中后序详解

【免费下载链接】LeetCode-Book 《剑指 Offer》 Python, Java, C++ 解题代码,LeetBook《图解算法数据结构》配套代码仓 【免费下载链接】LeetCode-Book 项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Book

引言:为什么树的遍历如此重要?

在计算机科学领域,树(Tree)作为一种非线性数据结构,广泛应用于数据库索引、编译器语法分析、人工智能决策等场景。树的遍历(Tree Traversal)是指按照某种规律访问树中所有节点的过程,它是树操作的基础。据统计,在LeetCode中等以上难度题目中,涉及树遍历的题目占比高达42%,而掌握前序、中序、后序(深度优先搜索DFS)和层序(广度优先搜索BFS)四大遍历方法,能解决80%以上的树类问题。

本文基于GitHub热门项目LeetCode-Book的源码实现,系统讲解树的四种核心遍历算法,包含15+代码示例、8张流程图和3组对比分析,帮助读者从原理到实战全面掌握这一核心技能。

一、深度优先搜索(DFS):沿着树的深度遍历

深度优先搜索(Depth-First Search, DFS)的核心思想是:沿着树的深度优先遍历节点,当无法继续前进时,回溯到上一节点。根据根节点访问顺序的不同,DFS可分为前序、中序和后序三种遍历方式。

1.1 前序遍历(Pre-order Traversal):根→左→右

定义:先访问根节点,再递归遍历左子树,最后递归遍历右子树。

应用场景:复制树、前缀表达式求值、获取树的结构信息。

算法流程图

mermaid

代码实现(Python)
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def dfs(node):
            if not node: return
            res.append(node.val)  # 根
            dfs(node.left)        # 左
            dfs(node.right)       # 右
        dfs(root)
        return res
执行过程示例

对于二叉树 [3,9,20,null,null,15,7]

遍历顺序:3 → 9 → 20 → 15 → 7
结果数组:[3,9,20,15,7]

1.2 中序遍历(In-order Traversal):左→根→右

定义:先递归遍历左子树,再访问根节点,最后递归遍历右子树。

特殊性质:对于二叉搜索树(BST),中序遍历结果为升序序列

算法流程图

mermaid

代码实现(Python)
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def dfs(node):
            if not node: return
            dfs(node.left)        # 左
            res.append(node.val)  # 根
            dfs(node.right)       # 右
        dfs(root)
        return res
实战应用:二叉搜索树的第k大节点

利用中序遍历的逆序(右→根→左)可高效找到BST的第k大节点:

class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        def dfs(node):
            if not node: return
            dfs(node.right)       # 右
            if self.k == 0: return
            self.k -= 1
            if self.k == 0: self.res = node.val
            dfs(node.left)        # 左
            
        self.k = k
        dfs(root)
        return self.res

1.3 后序遍历(Post-order Traversal):左→右→根

定义:先递归遍历左子树,再递归遍历右子树,最后访问根节点。

典型应用:计算树的深度、删除树节点、后缀表达式求值。

算法流程图

mermaid

代码实现(Python)
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def dfs(node):
            if not node: return
            dfs(node.left)        # 左
            dfs(node.right)       # 右
            res.append(node.val)  # 根
        dfs(root)
        return res
实战应用:计算二叉树的深度
class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        left_depth = self.maxDepth(root.left)   # 左子树深度
        right_depth = self.maxDepth(root.right) # 右子树深度
        return max(left_depth, right_depth) + 1 # 根节点深度

二、广度优先搜索(BFS):按层次遍历树结构

广度优先搜索(Breadth-First Search, BFS)的核心思想是:从根节点开始,逐层遍历树的节点。这种遍历方式能直观地反映树的层次结构,因此也称为层序遍历。

2.1 层序遍历(Level-order Traversal):从上到下,从左到右

定义:从根节点开始,依次访问每一层的节点,同一层节点按从左到右顺序访问。

数据结构:使用队列(Queue)实现,确保节点按先进先出顺序处理。

算法流程图

mermaid

代码实现(Python)
from collections import deque

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root: return []
        res = []
        queue = deque([root])
        
        while queue:
            node = queue.popleft()
            res.append(node.val)
            if node.left: queue.append(node.left)
            if node.right: queue.append(node.right)
        
        return res
分层输出优化

如需按层输出节点(如 [[3],[9,20],[15,7]]),可增加层级控制:

def levelOrder(root: TreeNode) -> List[List[int]]:
    if not root: return []
    res, queue = [], deque([root])
    
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left: queue.append(node.left)
            if node.right: queue.append(node.right)
        res.append(level)
    
    return res

三、四大遍历方法对比分析

3.1 时间复杂度与空间复杂度

遍历方法时间复杂度空间复杂度最差空间复杂度
前序遍历O(N)O(h)O(N)(斜树)
中序遍历O(N)O(h)O(N)(斜树)
后序遍历O(N)O(h)O(N)(斜树)
层序遍历O(N)O(w)O(N)(满二叉树)

注:N为节点总数,h为树的高度,w为树的最大宽度

3.2 递归与迭代实现对比

实现方式优点缺点适用场景
递归代码简洁、可读性强栈溢出风险、调试困难树高较小的情况
迭代无栈溢出风险代码复杂、需要手动维护栈树高较大或生产环境
迭代法实现前序遍历示例
def preorderTraversal(root: TreeNode) -> List[int]:
    if not root: return []
    res, stack = [], [root]
    
    while stack:
        node = stack.pop()
        res.append(node.val)
        if node.right: stack.append(node.right)  # 右子节点先入栈
        if node.left: stack.append(node.left)    # 左子节点后入栈
    
    return res

四、实战应用:从遍历序列重建二叉树

4.1 从前序与中序遍历序列构造二叉树

问题:已知二叉树的前序遍历 preorder 和中序遍历 inorder,重建该二叉树。

核心原理

  • 前序遍历的第一个元素为根节点
  • 中序遍历中,根节点左侧为左子树,右侧为右子树
算法流程图

mermaid

代码实现(Python)
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        # 哈希表存储中序序列值与索引映射
        inorder_map = {val: idx for idx, val in enumerate(inorder)}
        
        def build(pre_root, in_left, in_right):
            if in_left > in_right: return None
            
            # 构建根节点
            root_val = preorder[pre_root]
            root = TreeNode(root_val)
            
            # 找到中序序列中的根节点索引
            in_root = inorder_map[root_val]
            
            # 递归构建左右子树
            root.left = build(pre_root + 1, in_left, in_root - 1)
            root.right = build(pre_root + (in_root - in_left) + 1, in_root + 1, in_right)
            
            return root
        
        return build(0, 0, len(inorder) - 1)

五、LeetCode-Book项目中的遍历实践

LeetCode-Book项目提供了丰富的树遍历实战案例,以下是几个典型应用:

5.1 路径求和(剑指Offer 34)

使用前序遍历+回溯找到所有从根节点到叶节点的路径,其和等于目标值:

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        res, path = [], []
        
        def dfs(node, target):
            if not node: return
            path.append(node.val)
            target -= node.val
            
            # 找到符合条件的叶节点路径
            if target == 0 and not node.left and not node.right:
                res.append(list(path))
            
            dfs(node.left, target)
            dfs(node.right, target)
            path.pop()  # 回溯
        
        dfs(root, sum)
        return res

5.2 二叉树的镜像(剑指Offer 27)

使用后序遍历交换每个节点的左右子树:

class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root: return None
        
        # 递归处理左右子树
        left = self.mirrorTree(root.left)
        right = self.mirrorTree(root.right)
        
        # 交换左右子树
        root.left, root.right = right, left
        
        return root

六、总结与学习建议

6.1 遍历方法选择指南

应用场景推荐遍历方法时间复杂度
树的深度/高度计算后序遍历O(N)
树的层次结构展示层序遍历O(N)
二叉搜索树排序中序遍历O(N)
复制/序列化二叉树前序遍历O(N)
寻找最近公共祖先后序遍历O(N)

6.2 学习路径建议

  1. 基础阶段:掌握递归实现的四种遍历方法
  2. 进阶阶段:掌握迭代实现的四种遍历方法
  3. 应用阶段:练习从遍历序列重建二叉树、路径求和等综合题目
  4. 优化阶段:学习 Morris 遍历(常数空间复杂度遍历方法)

6.3 项目实践建议

LeetCode-Book项目中与树遍历相关的重点题目:

  • 剑指Offer 32:层序遍历的三种变形
  • 剑指Offer 54:中序遍历的逆序应用
  • 剑指Offer 68:后序遍历找最近公共祖先
  • 105题:前序+中序重建二叉树

通过这些题目的练习,可以深入理解树遍历的本质和应用场景。

附录:项目代码获取与贡献

项目地址:https://gitcode.com/GitHub_Trending/le/LeetCode-Book

该项目包含《剑指Offer》和《图解算法数据结构》的Python、Java、C++实现,所有树遍历相关代码位于:

  • sword_for_offer/codes/:剑指Offer题解
  • selected_coding_interview/docs/:精选面试题解

欢迎通过提交PR的方式贡献更优的遍历实现或新的应用案例。

【免费下载链接】LeetCode-Book 《剑指 Offer》 Python, Java, C++ 解题代码,LeetBook《图解算法数据结构》配套代码仓 【免费下载链接】LeetCode-Book 项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Book

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值