当前位置: 首页 > news >正文

94. 二叉树的中序遍历详解:迭代法核心逻辑与出入栈模拟

中序遍历是二叉树遍历中最经典的算法之一,其核心顺序是 “左子树 → 根节点 → 右子树”。递归实现非常简单,但理解迭代法的实现却需要掌握栈的操作细节。本文将通过代码逐行解析,结合出入栈的模拟,彻底讲透迭代法的核心逻辑。


题目描述

给定一个二叉树的根节点 root,返回它的 中序 遍历结果。例如,输入 root = [1,null,2,3],输出 [1,3,2]


核心难点分析

1. 出入栈顺序

  • 何时入栈? 当当前节点存在左子树时,不断向左深入,将所有左节点入栈。
  • 何时出栈? 当左子树遍历到底(tempnull)时,弹出栈顶元素,处理该节点,并转向其右子树。

2. 循环的逻辑

  • 循环条件temp != null || !stack.isEmpty()
    • temp != null:表示仍有左子树需要探索;
    • !stack.isEmpty():表示需要回溯到之前的节点处理右子树。

3. 规律总结

  • “有左入左,无左入右,自底向上”
    • 有左子树时,持续向左入栈;
    • 无左子树时,弹出栈顶节点,记录值,并转向右子树;
    • 最终遍历顺序是从最左节点开始,自底向上处理。

解题思路分步解析

步骤 1:初始化栈和结果列表

List<Integer> res = new ArrayList<>();  // 存储遍历结果
Stack<TreeNode> stack = new Stack<>();  // 模拟递归的栈
TreeNode temp = root;                   // 当前处理节点

步骤 2:循环处理节点

while (temp != null || !stack.isEmpty()) {// 1. 有左子树:持续向左深入,节点入栈if (temp != null) {stack.push(temp);temp = temp.left;}// 2. 无左子树:弹出栈顶节点,记录值,转向右子树else {temp = stack.pop();res.add(temp.val);temp = temp.right;}
}

出入栈模拟示例

以二叉树 [1,2,3,4,5] 为例,结构如下:

    1/ \2   3/ \
4   5

中序遍历结果应为 [4,2,5,1,3]。以下是栈的变化过程:

当前 temp栈内容(底→顶)操作结果 res
1[]压入 1,转向左子 2[]
2[1]压入 2,转向左子 4[]
4[1,2]压入 4,转向左子 null[]
null[1,2,4]弹出 4,记录 4,转向右子 null[4]
null[1,2]弹出 2,记录 2,转向右子 5[4,2]
5[1]压入 5,转向左子 null[4,2]
null[1,5]弹出 5,记录 5,转向右子 null[4,2,5]
null[1]弹出 1,记录 1,转向右子 3[4,2,5,1]
3[]压入 3,转向左子 null[4,2,5,1]
null[3]弹出 3,记录 3,转向右子 null[4,2,5,1,3]

关键知识点总结

1. 为什么用栈?

  • 模拟递归调用栈:递归的本质是系统维护的栈,迭代法通过显式栈手动模拟这一过程。
  • 避免栈溢出:当树深度较大时,递归可能引发栈溢出,迭代法更安全。

2. 循环条件的意义

  • temp != null:表示当前仍有未探索的左子树。
  • !stack.isEmpty():表示需要回溯到之前的节点处理右子树。

3. 时间复杂度与空间复杂度

  • 时间复杂度:O(n),每个节点恰好被访问两次(入栈和出栈)。
  • 空间复杂度:O(n),最坏情况下栈存储所有节点。

完整代码

class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();TreeNode temp = root;while (temp != null || !stack.isEmpty()) {          if (temp != null) {stack.push(temp);temp = temp.left;} else {temp = stack.pop();res.add(temp.val);temp = temp.right;}}return res;}
}

总结

中序遍历的迭代法核心在于 “左-根-右” 的顺序控制。通过栈的压入和弹出操作,可以精确模拟递归的调用过程。关键在于:

  1. 向左深入到底,将所有左节点入栈;
  2. 回溯处理右子树,利用栈实现自底向上的遍历。
    掌握这一逻辑后,可以轻松应对二叉树相关的其他迭代遍历问题(如前序、后序)。
http://www.xdnf.cn/news/441451.html

相关文章:

  • 关于数据湖和数据仓的一些概念
  • 深入解析JVM字节码解释器执行流程(OpenJDK 17源码实现)
  • 44、私有程序集与共享程序集有什么区别?
  • 工具学习_模糊测试
  • 中天互联在数据采集方面有哪些优势?
  • 初探 Skynet:轻量级分布式游戏服务器框架实战
  • 二叉树——层序遍历
  • MCU程序加密保护(二)ID 验证法 加密与解密
  • SCDN如何有效防护网站免受CC攻击?——安全加速网络的实战解析
  • 深度强化学习 | 图文详细推导软性演员-评论家SAC算法原理
  • FPGA: Xilinx Kintex 7实现PCIe接口
  • 数据库基础复习笔记
  • 量子计算实用化突破:从云端平台到国际竞合,开启算力革命新纪元
  • 40:相机与镜头选型
  • 虚幻引擎5-Unreal Engine笔记之Qt与UE中的Meta和Property
  • 云图库和黑马点评的项目学习经验
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: 获取macOS App的Bundle路径信息.
  • list 容器常见用法及实现
  • 基于运动补偿的前景检测算法
  • loss = -F.log_softmax(logits[:, -1, :], dim=1)[0, irrational_id]
  • 【C/C++】自定义类型:结构体
  • Seata源码—2.seata-samples项目介绍
  • 酒店行业冰与火:一边流拍,一边扩张
  • 大模型高效微调技术:从原理到实战应用
  • 深入理解Java适配器模式:从接口兼容到设计哲学
  • Python调用SQLite及pandas相关API详解
  • 解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs-强化学习算法
  • 机器学习第十一讲:标准化 → 把厘米和公斤单位统一成标准值
  • 对抗系统熵增:从被动救火到主动防御的稳定性实战
  • R利用spaa包计算植物/微生物的生态位宽度和重叠指数