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

二叉树前中后序遍历统一迭代法详解:空标记法与栈操作的艺术

二叉树的 前序中序后序 遍历是算法中的经典问题。递归实现简单直观,而迭代法则能更好地理解栈的操作逻辑。前文中(中序,前序与后序)所讲过传统的迭代法需要为每种遍历设计不同的入栈顺序,但 统一迭代法 通过引入 空标记节点,将三种遍历的代码结构统一,极大降低了记忆难度。本文将结合代码与出入栈模拟,深入解析这一技巧的核心思想。


一、统一迭代法的核心思想

1. 为什么需要空标记?

在传统迭代法中,前序、中序、后序遍历的栈操作逻辑差异较大,难以统一。空标记法 的核心在于将 节点的访问值的记录 分离:

  • 访问节点:将节点按遍历顺序的逆序压入栈(例如前序需先处理根,因此根先入栈)。
  • 记录值:当遇到空标记时,表示当前栈顶节点已完成子节点处理,可以记录其值。

2. 统一操作步骤

  1. 节点入栈:按遍历顺序的逆序压入节点及其子节点。
  2. 插入空标记:在需要记录值的节点后压入 null 作为标记。
  3. 处理标记:当栈顶为 null 时,弹出 null 并记录下一个节点的值。

二、前序遍历

1. 代码解析

class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if (root == null) return res;stack.push(root);while (!stack.isEmpty()) {TreeNode node = stack.peek();if (node != null) {stack.pop();// 前序逆序入栈:根 → 右 → 左 → null标记 → 根if (node.right != null) stack.push(node.right);if (node.left != null) stack.push(node.left);stack.push(node);stack.push(null); // 插入空标记} else {stack.pop(); // 弹出 nullnode = stack.pop();res.add(node.val);}}return res;}
}

2. 出入栈模拟(以 [1,2,3] 为例)

栈内容(底→顶)操作结果 res
[1]初始状态[]
[1.right(3),1.left(2),1,null]弹出 1,按右左顺序重新入栈[]
[3,2,1,null]处理非空节点 1[]
[3,2,1,null] → 弹出 null遇到 null,记录 1[1]
[3,2]处理 2[1]
[3,2.right(null),2.left(null),2,null]弹出 2,入栈子节点[1]
[3,2,null] → 弹出 null记录 2[1,2]
[3]处理 3[1,2]
[3.right(null),3.left(null),3,null]弹出 3,入栈子节点[1,2]
[3,null] → 弹出 null记录 3[1,2,3]

三、中序遍历

1. 代码解析

class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if (root == null) return res;stack.push(root);while (!stack.isEmpty()) {TreeNode node = stack.peek();if (node != null) {stack.pop();// 中序逆序入栈:右 → 根 → null标记 → 左if (node.right != null) stack.push(node.right);stack.push(node);stack.push(null);if (node.left != null) stack.push(node.left);} else {stack.pop(); // 弹出 nullnode = stack.pop();res.add(node.val);}}return res;}
}

2. 出入栈模拟(以 [1,2,3] 为例)

栈内容(底→顶)操作结果 res
[1]初始状态[]
[1.right(3),1,null,1.left(2)]弹出 1,按右根左顺序入栈[]
[3,1,null,2]处理非空节点 2[]
[3,1,null,2.right(null),2,null,2.left(null)]弹出 2[]
[3,1,null,2,null] → 弹出 null记录 2[2]
[3,1,null] → 弹出 null记录 1[2,1]
[3]处理 3[2,1]
[3.right(null),3,null,3.left(null)]弹出 3[2,1]
[3,null] → 弹出 null记录 3[2,1,3]

四、后序遍历

1. 代码解析

class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if (root == null) return res;stack.push(root);while (!stack.isEmpty()) {TreeNode node = stack.peek();if (node != null) {stack.pop();// 后序逆序入栈:根 → null标记 → 右 → 左stack.push(node);stack.push(null);if (node.right != null) stack.push(node.right);if (node.left != null) stack.push(node.left);} else {stack.pop(); // 弹出 nullnode = stack.pop();res.add(node.val);}}return res;}
}

2. 出入栈模拟(以 [1,2,3] 为例)

栈内容(底→顶)操作结果 res
[1]初始状态[]
[1,null,1.right(3),1.left(2)]弹出 1,按根右左顺序入栈[]
[null,3,2]处理非空节点 2[]
[null,3,2.right(null),2,null,2.left(null)]弹出 2[]
[null,3,2,null] → 弹出 null记录 2[2]
[null,3] → 弹出 null记录 3[2,3]
[null] → 弹出 null记录 1[2,3,1]

五、关键知识点总结

1. 统一迭代法的优势

  • 代码结构统一:三种遍历的代码逻辑高度相似,只需调整入栈顺序。
  • 逻辑清晰:通过空标记明确区分节点的访问和值记录阶段。

2. 入栈顺序的规律

遍历方式入栈顺序(逆序)实际遍历顺序
前序右 → 左 → 根 → null根 → 左 → 右
中序右 → 根 → null → 左左 → 根 → 右
后序根 → null → 右 → 左左 → 右 → 根

3. 复杂度分析

  • 时间复杂度:O(n),每个节点入栈和出栈两次。
  • 空间复杂度:O(n),栈存储所有节点。

六、总结

统一迭代法的核心在于 空标记 的引入,通过将节点的访问和值记录分离,实现了三种遍历的逻辑统一。关键点总结:

  1. 逆序入栈:按遍历顺序的逆序压入节点。
  2. 空标记触发记录:遇到 null 时记录栈顶节点的值。
  3. 调整顺序即可切换遍历方式:只需修改入栈顺序,无需重写逻辑。

掌握这一方法后,可以轻松应对二叉树遍历的所有变体问题!

相关文章:

  • LIO-SAM框架理解
  • 鸿蒙OSUniApp 实现精美的用户登录和注册页面#三方框架 #Uniapp
  • html5+css3实现傅里叶变换的动态展示效果(仅供参考)
  • Pytorch的Dataloader使用详解
  • 【USRP】在linux下安装python API调用
  • Oracle 中的虚拟列Virtual Columns和PostgreSQL Generated Columns生成列
  • 一分钟了解大语言模型(LLMs)
  • 基于ssm+mysql的高校设备管理系统(含LW+PPT+源码+系统演示视频+安装说明)
  • 音频分类的学习
  • De-biased Attention Supervision for Text Classifcation with Causality
  • 学习51单片机01(安装开发环境)
  • 基于Matlab的非线性Newmark法用于计算结构动力响应
  • STM32 之网口资源
  • 当 DeepSeek 遇见区块链:一场颠覆式的应用革命
  • 学习黑客蓝牙技术详解
  • SAP Fiori Elements Object Page
  • rocketmq 拉取消息
  • AI智能体 | 使用Coze一键制作“假如书籍会说话”视频,18个作品狂吸17.6万粉,读书博主新标杆!(附保姆级教程)
  • 输入一个正整数,将其各位数字倒序输出(如输入123,输出321)
  • 【行为型之模板方法模式】游戏开发实战——Unity标准化流程与可扩展架构的核心实现
  • 92岁上海交大退休教师捐赠百万元给学校,其父也曾设奖学金
  • 博柏利上财年营收下降17%,计划裁员1700人助推股价涨超18%
  • 马上评|“衣服越来越难买”,对市场是一个提醒
  • 违法违规收集使用个人信息,爱奇艺、轻颜等65款App被点名
  • “降息潮”延续,多家民营银行下调存款利率
  • 中国潜水救捞行业协会发布《呵护潜水员职业健康安全宣言》