LeetCode-Py 项目:二叉树遍历算法详解

LeetCode-Py 项目:二叉树遍历算法详解

LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

引言

二叉树是计算机科学中最基础也是最重要的数据结构之一,在算法面试和实际开发中都有着广泛应用。本文将深入讲解二叉树的四种基本遍历方式:前序遍历、中序遍历、后序遍历和层序遍历,帮助读者全面掌握二叉树遍历的核心思想与实现方法。

1. 二叉树遍历概述

二叉树遍历是指按照特定顺序访问树中所有节点的过程。根据访问顺序的不同,主要分为两大类遍历方式:

1.1 深度优先遍历 (DFS)

  • 前序遍历:根节点 → 左子树 → 右子树
  • 中序遍历:左子树 → 根节点 → 右子树
  • 后序遍历:左子树 → 右子树 → 根节点

1.2 广度优先遍历 (BFS)

  • 层序遍历:按层次从上到下,每层从左到右访问

理解这些遍历方式对于解决二叉树相关问题至关重要,比如:

  • 前序遍历常用于复制二叉树
  • 中序遍历常用于二叉搜索树的有序输出
  • 后序遍历常用于计算表达式树
  • 层序遍历常用于寻找最短路径或树的宽度

2. 前序遍历详解

2.1 递归实现

递归实现是最直观的方式,完全遵循前序遍历的定义:

def preorderTraversal(root):
    res = []
    def traverse(node):
        if not node:
            return
        res.append(node.val)  # 访问根节点
        traverse(node.left)   # 遍历左子树
        traverse(node.right)  # 遍历右子树
    traverse(root)
    return res

时间复杂度:O(n),每个节点访问一次 空间复杂度:O(h),h为树的高度,递归栈的深度

2.2 迭代实现

使用显式栈模拟递归过程:

def preorderTraversal(root):
    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

这种实现巧妙地利用了栈的LIFO特性,确保访问顺序为根→左→右。

3. 中序遍历详解

3.1 递归实现

def inorderTraversal(root):
    res = []
    def traverse(node):
        if not node:
            return
        traverse(node.left)   # 遍历左子树
        res.append(node.val)  # 访问根节点
        traverse(node.right)  # 遍历右子树
    traverse(root)
    return res

3.2 迭代实现

中序遍历的迭代实现较为复杂,需要维护当前节点指针:

def inorderTraversal(root):
    res = []
    stack = []
    curr = root
    while curr or stack:
        while curr:  # 深入左子树
            stack.append(curr)
            curr = curr.left
        curr = stack.pop()
        res.append(curr.val)  # 访问节点
        curr = curr.right     # 转向右子树
    return res

关键点在于:先将所有左子节点压栈,然后弹出访问,再处理右子树。

4. 后序遍历详解

4.1 递归实现

def postorderTraversal(root):
    res = []
    def traverse(node):
        if not node:
            return
        traverse(node.left)   # 遍历左子树
        traverse(node.right)  # 遍历右子树
        res.append(node.val)  # 访问根节点
    traverse(root)
    return res

4.2 迭代实现

后序遍历的迭代实现最为复杂,需要记录前一个访问的节点:

def postorderTraversal(root):
    res = []
    stack = []
    prev = None
    while root or stack:
        while root:
            stack.append(root)
            root = root.left
        root = stack.pop()
        if not root.right or root.right == prev:
            res.append(root.val)
            prev = root
            root = None
        else:
            stack.append(root)
            root = root.right
    return res

这种实现确保在访问节点前,其左右子树都已被访问。

5. 层序遍历详解

层序遍历使用队列实现广度优先搜索:

def levelOrder(root):
    if not root:
        return []
    res = []
    queue = [root]
    while queue:
        level_size = len(queue)
        level = []
        for _ in range(level_size):
            node = queue.pop(0)
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        res.append(level)
    return res

关键点在于:

  1. 使用队列先进先出的特性
  2. 记录每层的节点数,确保分层存储结果
  3. 时间复杂度O(n),空间复杂度O(n)

6. 遍历方式对比与应用

| 遍历方式 | 访问顺序 | 典型应用场景 | |---------|---------|-------------| | 前序 | 根→左→右 | 复制二叉树,序列化 | | 中序 | 左→根→右 | 二叉搜索树有序输出 | | 后序 | 左→右→根 | 表达式求值,释放内存 | | 层序 | 按层访问 | 寻找最短路径,计算树宽 |

7. 总结

掌握二叉树的四种基本遍历方式是算法学习的基础。本文详细介绍了:

  1. 每种遍历方式的递归和迭代实现
  2. 各种实现的时间空间复杂度分析
  3. 不同遍历方式的应用场景

建议读者通过实际编码练习来巩固这些知识,理解不同遍历方式的本质区别。对于更复杂的二叉树问题,往往需要结合多种遍历方式来解决。

LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石玥含Lane

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值