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. 右子树:递归遍历右子树

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

总结:

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

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

核心要点:

  • 遍历顺序:牢记"左根右"的中序遍历顺序
  • 递归思想:分治思想,将问题分解为子树问题
  • 栈的应用:迭代法通过栈模拟递归调用的过程
  • 空间优化:两种方法的空间复杂度都与树高相关
相关推荐
Wang ruoxi1 天前
Pygame 小游戏——数独
开发语言·python·pygame
吠品1 天前
处理 Python 类继承中那些变来变去的初始化参数
linux·前端·python
aqiu1111111 天前
python02
算法
瓦特what?1 天前
位运算核心技巧与应用
java·jvm·算法
无限码力1 天前
阿里算法岗 0530笔试真题 - 荆棘林的最优砍断计划
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试真题·阿里巴巴笔试真题
人道领域1 天前
【LeetCode刷题日记】90.子集Ⅱ--- 归纳题解
java·开发语言·leetcode
会Tk矩阵群控的小木1 天前
小红书矩阵软件:基于Python+ADB的多设备批量管理自动化脚本实战
运维·python·adb·矩阵·自动化·新媒体运营·个人开发
随意起个昵称1 天前
线性dp-LIS题目5(导弹拦截,二分优化)
c++·算法·动态规划
winlife_1 天前
全程用 AI 做一款商业级手游 · EP10 道具系统:让三个按钮真正改变棋盘
windows·算法·unity·ai编程·游戏开发·mcp·玩法系统
计算机安禾1 天前
【数据库系统原理】第16篇:范式理论(下):多值依赖与第四范式——消除非平凡的非函数依赖
算法