LeetCode hot100:094 二叉树的中序遍历:从递归到迭代的完整指南

问题描述:

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

示例1:

**输入:**root = [1,null,2,3]

输出:[1,3,2]

示例2:

**输入:**root = []

输出:[]

示例3:

**输入:**root = [1]

输出:[1]

解决方法:

方法一:递归法

算法思路:

递归法利用函数调用栈来模拟遍历过程,遵循"左子树-根节点-右子树"的访问顺序,将大问题分解为小问题:遍历整棵树 = 遍历左子树 + 访问根节点 + 遍历右子树。

算法步骤:

  1. 递归终止条件:如果当前节点为空,直接返回

  2. 递归左子树:深入遍历当前节点的左子树

  3. 访问根节点:将当前节点的值加入结果列表

  4. 递归右子树:深入遍历当前节点的右子树

代码实现:

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        # 调用辅助递归函数,从根节点开始遍历
        self.inorder(root,result)
        return result

    def inorder(self,node,result):
        # 递归终止条件
        if node is None:
            return
        # 递归遍历左子树  深入当前节点的左子树 直到最左边叶子节点
        self.inorder(node.left,result)
        # 访问当前节点-根节点   在左子树遍历完成后,将当前节点的值加入结果列表
        result.append(node.val)
        # 递归遍历右子树 在访问完当前节点后,深入右子树继续遍历
        self.inorder(node.right,result)

# self 是 Python 类方法的第一个参数,代表实例本身

# 在类的方法中调用其他方法必须使用 self.方法名()

# 这是 Python 面向对象编程的语法要求,不是算法本身的需要

复杂度分析:

  • 时间复杂度:O(n),每个节点恰好被访问一次
  • 空间复杂度:O(h),h为二叉树的高度

方法二:迭代法

算法思路:

使用显式的栈来模拟递归的函数调用栈。通过循环和栈操作来实现中序遍历的"左根右"顺序。核心思想是先深入左子树到底部,然后回溯访问节点,再转向右子树。

算法步骤;

  1. 初始化:创建结果列表、辅助栈,设置当前节点指针

  2. 循环条件:当前节点不为空或栈不为空时继续

  3. 左子树处理:将当前节点及其所有左子节点入栈

  4. 节点访问:弹出栈顶节点,访问该节点

  5. 右子树处理:转向右子树继续遍历

代码实现:

python 复制代码
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # 步骤1:初始化
        result = []    # 存储结果
        stack = []     # 辅助栈
        current = root # 当前节点指针
        
        # 步骤2:循环条件
        while current or stack:
            # 步骤3:左子树处理 - 遍历到最左边的节点
            while current:
                stack.append(current)
                current = current.left
            
            # 步骤4:节点访问 - 弹出栈顶元素并访问
            current = stack.pop()
            result.append(current.val)
            
            # 步骤5:右子树处理 - 转向右子树
            current = current.right
            
        return result

复杂度分析:

  • 时间复杂度:O(n),每个节点入栈出栈各一次,共 2n 次操作
  • 空间复杂度:O(h),h为二叉树的高度

递归法另一种版本(条件判断)

python 复制代码
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # 步骤1:初始化
        result = []
        stack = []
        current = root
        
        # 步骤2:循环条件
        while current or stack:
            if current:
                # 步骤3:节点非空 - 入栈并转向左子树
                stack.append(current)
                current = current.left
            else:
                # 步骤4:节点为空 - 回溯访问并转向右子树
                current = stack.pop()
                result.append(current.val)
                current = current.right
                
        return result

问题详解:

什么是中序遍历?

中序遍历是二叉树遍历的一种方式,遍历顺序为:

  1. 左子树:递归遍历左子树

  2. 根节点:访问当前节点

  3. 右子树:递归遍历右子树

此外还有前序遍历 (根左右)以及后序遍历(左右根)

总结:

| 方法 | 优点 | 缺点 | 适用场景 |
| 递归法 | 代码简洁,逻辑清晰 | 递归深度大时可能会栈溢出 | 树深度不大 |

迭代法 避免递归开销,可控性好 代码相对复杂 深度大的树

核心要点:

  • 遍历顺序:牢记"左根右"的中序遍历顺序
  • 递归思想:分治思想,将问题分解为子树问题
  • 栈的应用:迭代法通过栈模拟递归调用的过程
  • 空间优化:两种方法的空间复杂度都与树高相关
相关推荐
ins_lizhiming3 小时前
在华为910B GPU服务器上运行DeepSeek-R1-0528模型
人工智能·pytorch·python·华为
麦麦大数据3 小时前
F049 知识图谱双算法推荐在线学习系统vue+flask+neo4j之BS架构开题论文全源码
学习·算法·知识图谱·推荐算法·开题报告·学习系统·计算机毕业设计展示
bwz999@88.com3 小时前
win10安装miniforge+mamba替代miniconda
python
兩尛3 小时前
215. 数组中的第K个最大元素
数据结构·算法·排序算法
952363 小时前
数据结构-堆
java·数据结构·学习·算法
吃着火锅x唱着歌3 小时前
LeetCode 面试题 16.24.数对和
算法·leetcode·职场和发展
不会编程的小寒3 小时前
数据结构 2.0
数据结构·算法
专注VB编程开发20年3 小时前
图片转矢量图(提取轮廓线条)Potrace:一个基于多边形的位图轮廓矢量化算法(translation)
算法·图片转矢量