面包屑图标 当前位置: 首页
AI资讯
热点详情

二叉树前中后序统一迭代法

AI热点日报
AI热点日报时间:2026-07-07
热点解读

说到二叉树的遍历,递归写法大家都觉得挺优雅的,前中后序也就是调调节点顺序的事。但一旦切换到迭代法,事情就开始变得拧巴了——前序和后序勉强能用一套逻辑写下来,中序却完全是另一套玩法,一会儿栈,一会儿指针,折腾半天写出来三套风格各异的代码。 不过其实,迭代法也能写出统一风格的代码,关键就在于一个很巧妙的

说到二叉树的遍历,递归写法大家都觉得挺优雅的,前中后序也就是调调节点顺序的事。但一旦切换到迭代法,事情就开始变得拧巴了——前序和后序勉强能用一套逻辑写下来,中序却完全是另一套玩法,一会儿栈,一会儿指针,折腾半天写出来三套风格各异的代码。

不过其实,迭代法也能写出统一风格的代码,关键就在于一个很巧妙的小技巧:标记法

二叉树的统一迭代法

先说原因。之前用栈模拟迭代遍历时,碰到的核心矛盾是:访问节点和处理节点的时机不一致。中序遍历需要先“路过”根节点,但只有当左子树处理完,才能回头处理根节点——而栈的后进先出特性,让它很难同时处理好“路过”和“处理”这两个动作。

那怎么解决?简单粗暴:把要处理的节点也扔进栈里,但做个标记。具体做法是,当某个节点需要“被处理”(即加入结果集)时,我们往栈里再塞一个空指针作为哨兵。

来看中序遍历的代码,配合动画更容易理解:

class Solution { public: vector inorderTra versal(TreeNode* root) { vector result; stack st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); if (node->right) st.push(node->right); st.push(node); st.push(NULL); if (node->left) st.push(node->left); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };

动画中,result数组就是最终结果集。

核心逻辑是这样:我们先把所有节点(包括根节点)当作“待访问”的节点入栈。当碰到一个非空节点时,它还不急着处理,而是跟着它的右、中、左子节点一起再按顺序入栈,同时在中节点后面加一个空指针作为标记。只有当弹出的是一个空指针时,才说明栈顶的下一个节点已经被访问过,可以放进结果集了。

这个思路一打通,前序和后序就简单了:只需要调整入栈顺序就行。

迭代法前序遍历

前序遍历和中序遍历相比,仅仅改变了两行代码的顺序:

class Solution { public: vector preorderTra versal(TreeNode* root) { vector result; stack st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); if (node->right) st.push(node->right); if (node->left) st.push(node->left); st.push(node); st.push(NULL); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };

迭代法后序遍历

后序遍历也一样,只是入栈顺序变成中、右、左:

class Solution { public: vector postorderTra versal(TreeNode* root) { vector result; stack st; if (root != NULL) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != NULL) { st.pop(); st.push(node); st.push(NULL); if (node->right) st.push(node->right); if (node->left) st.push(node->left); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };

总结

这一套标记法下来,前中后序的迭代代码终于不再各自为战了,只要改几行入栈顺序就能互相转换。但说实话,这个写法理解起来需要点时间,面试时直接手写也有一定难度。所以大家可以根据自己的习惯,选择一种自己最容易理解的递归或迭代法来掌握就好——不必强求统一。

其他语言版本

Ja va 迭代法前序遍历:

class Solution { public List preorderTra versal(TreeNode root) { List result = new LinkedList<>(); Stack st = new Stack<>(); if (root != null) st.push(root); while (!st.empty()) { TreeNode node = st.peek(); if (node != null) { st.pop(); if (node.right != null) st.push(node.right); if (node.left != null) st.push(node.left); st.push(node); st.push(null); } else { st.pop(); node = st.peek(); st.pop(); result.add(node.val); } } return result; } }

Ja va 迭代法中序遍历:

class Solution { public List inorderTra versal(TreeNode root) { List result = new LinkedList<>(); Stack st = new Stack<>(); if (root != null) st.push(root); while (!st.empty()) { TreeNode node = st.peek(); if (node != null) { st.pop(); if (node.right != null) st.push(node.right); st.push(node); st.push(null); if (node.left != null) st.push(node.left); } else { st.pop(); node = st.peek(); st.pop(); result.add(node.val); } } return result; } }

Ja va 迭代法后序遍历:

class Solution { public List postorderTra versal(TreeNode root) { List result = new LinkedList<>(); Stack st = new Stack<>(); if (root != null) st.push(root); while (!st.empty()) { TreeNode node = st.peek(); if (node != null) { st.pop(); st.push(node); st.push(null); if (node.right != null) st.push(node.right); if (node.left != null) st.push(node.left); } else { st.pop(); node = st.peek(); st.pop(); result.add(node.val); } } return result; } }

Python 迭代法前序遍历:

class Solution: def preorderTra versal(self, root: TreeNode) -> List[int]: result = [] st = [] if root: st.append(root) while st: node = st.pop() if node != None: if node.right: st.append(node.right) if node.left: st.append(node.left) st.append(node) st.append(None) else: node = st.pop() result.append(node.val) return result

Python 迭代法中序遍历:

class Solution: def inorderTra versal(self, root: TreeNode) -> List[int]: result = [] st = [] if root: st.append(root) while st: node = st.pop() if node != None: if node.right: st.append(node.right) st.append(node) st.append(None) if node.left: st.append(node.left) else: node = st.pop() result.append(node.val) return result

Python 迭代法后序遍历:

class Solution: def postorderTra versal(self, root: TreeNode) -> List[int]: result = [] st = [] if root: st.append(root) while st: node = st.pop() if node != None: st.append(node) st.append(None) if node.right: st.append(node.right) if node.left: st.append(node.left) else: node = st.pop() result.append(node.val) return result

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:二叉树前中后序统一迭代法要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://m.elecfans.com/article/1871375.html
二叉树

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-07 20:10
Dzine AI图像设计工具 卓越构图与风格控制

Dzine是一款强调构图控制与风格管理的AI图像设计工具,提供样式库、图层操作、定位和素描工具,支持文生图与图生图,具备生成填充编辑、一键修复增强及最高6144像素超高清导出功能,降低设计门槛,兼顾新手与专业用户。

AI热点2026-07-07 20:09
Arrival基于云的SaaS解决方案

3D虚拟空间的搭建,过去往往依赖专业建模软件和大量手动操作,技术门槛相当高。但现在,一款名为Arrival的云端SaaS解决方案正凭借AI与拖放功能,将这件事变得像搭积木一样轻松便捷。 什么是Arrival? Arrival本质上是一套专业的软件工具,核心目标就是帮助用户快速构建一个3D虚拟空间。它

AI热点2026-07-07 20:09
AI用户访谈:洞察需求加速产品市场匹配

ZENAI通过AI自动完成用户访谈,省去人工招募与主持流程,并自动总结用户场景、痛点及人物画像。产品经理、设计师、研究员可借此快速验证假设、提炼场景、获取市场洞察,加速产品市场契合度(PMF)达成,提供基础与专业两种套餐。

AI热点2026-07-07 20:09
Meshcapade ME AI生成逼真数字人头像平台

MeshcapadeMe基于SMPL人体模型技术,提供API接口支持图像、视频、测量及3D扫描输入,自动生成统一格式的逼真数字分身,无需专业建模技能即可将各类素材转化为可动画、跨平台使用的数字人类,适用于虚拟现实、游戏与影视等领域。

延伸阅读