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

学完递归,学二叉树的迭代遍历

什么是递归,什么是迭代!

刚刚学的层层嵌套,就是递归(我感觉更直观些)

for,while循环,就是迭代。

数学代码对比(绝对简单)

我们算一个超级简单的数学题:求 1 + 2 + 3 + ... + n 的和

写法一:迭代(循环,自己控制进度)
int sum_iterative(int n) { int result = 0; for (int i = 1; i <= n; i++) { // 我用 i 手动控制当前走到哪了 result = result + i; } return result; }

计算机在干嘛?它只负责重复执行大括号里的代码。没有任何“暂停”和“回头”,一路加到 n 结束。

写法二:递归(函数调自己,系统帮你暂停)
int sum_recursive(int n) { if (n == 1) return 1; // 停止条件 return n + sum_recursive(n - 1); // 在这里暂停! }

计算机在干嘛?假设你调用sum_recursive(5)

  1. 计算机看到5 + sum_recursive(4),它必须先去算sum_recursive(4)

  2. 于是它暂停当前的计算(在内存里记下“这里有个 5 等着加”),去算sum_recursive(4)

  3. sum_recursive(4)时,看到4 + sum_recursive(3),又暂停,去算sum_recursive(3)……

  4. 直到算到sum_recursive(1) = 1,开始逐层回头:1+2=3,3+3=6,6+4=10,10+5=15。

前序遍历:

核心规则(死记这一句)

前序遍历顺序是:中 -> 左 -> 右(先处理根,再处理左,最后处理右)

在迭代法中,为了实现“先左后右”,入栈时必须反着来:先压入右孩子,再压入左孩子。

因为栈(Stack)是后进先出(LIFO)——后放进去的先拿出来。为了让左孩子先被拿出来处理,就必须让左孩子最后放进去。

放根 ➡️ 取根(记录) ➡️ 放右 ➡️ 放左

class Solution { public: vector<int> preorderTraversal(TreeNode* root) { stack<TreeNode*> st; vector<int> result; if (root == NULL) return result; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); // 中 st.pop(); result.push_back(node->val); if (node->right) st.push(node->right); // 右(空节点不入栈) if (node->left) st.push(node->left); // 左(空节点不入栈) } return result; } };

接下来,再用迭代法写中序遍历的时候,会发现套路又不一样了,目前的前序遍历的逻辑无法直接应用到中序遍历上。

中序遍历(迭代法)

  • 中序是:一路向左,入栈存;无路可走,出栈记;转向右边,再来一次。

class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; TreeNode* cur = root; while (cur != NULL || !st.empty()) { if (cur != NULL) { // 指针来访问节点,访问到最底层 st.push(cur); // 将访问的节点放进栈 cur = cur->left; // 左 } else { cur = st.top(); // 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据) st.pop(); result.push_back(cur->val); // 中 cur = cur->right; // 右 } } return result; } };

后序遍历

把前序左右翻一下,就是中右左,反着输出就是左右中。

class Solution { public: vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*> st; vector<int> result; if (root == NULL) return result; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); st.pop(); result.push_back(node->val); if (node->left) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈) if (node->right) st.push(node->right); // 空节点不入栈 } reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了 return result; } };
http://www.jsqmd.com/news/1220003/

相关文章:

  • GHelper终极指南:如何用轻量级工具彻底掌控华硕笔记本性能
  • 嵌入式Linux开发新范式:TI主线内核策略解析与实战指南
  • Ryujinx:当C遇上Nintendo Switch——现代模拟器架构的深度解析
  • 2026年7月亨得利中国区售后服务网络更新优化 全国60+门店地址及电话汇总 - 亨得利客户服务中心
  • Ventoy终极指南:免费创建多系统启动盘,告别反复格式化
  • 如何用SRWE窗口编辑器解锁Windows应用的终极显示自由?
  • 平顶山卖金不踩坑!6家靠谱黄金回收店盘点,覆盖全市10个区县,上门秒到账! - 清奢黄金上门回收
  • AM261x UART CIR模式配置详解:红外通信调制频率、占空比与接收难题破解
  • Alacritty-Themes社区指南:如何参与开源贡献的5个简单步骤
  • 大白话完整梳理:嵌入向量到底是什么、怎么用
  • 革命性社交媒体图文工具:Guizang Social Card Skill完全指南 — 小红书与公众号封面一键生成
  • Wav2Lip UHQ技术架构解析:AI唇形同步的深度优化方案
  • 【AI数字人直播落地实战指南】:0代码搭建高转化直播间,3天上线+92%复购率提升路径
  • 如何在5分钟内用AI制作专业短视频?Pixelle-Video的完整免费指南
  • Windows 11系统优化终极指南:如何用Win11Debloat让你的电脑更快更干净
  • 2026年亨得利中国区售后服务网络更新优化,全国唯一售后热线以及线下网点地址 - 亨得利客户服务中心
  • SegmenTron模型评估全流程:Mean IoU计算与性能优化实战
  • Containerum团队协作功能完全指南:权限管理与项目协作的10个实用技巧
  • 2026宜兴降温冰块公司复购Top榜:良臣制冰厂凭什么稳居第一? - 热点咨讯
  • 自动化构建docker-alpine-java镜像:generate_dockerfiles.sh脚本完全指南
  • 【Copilot公式性能黑箱】:为什么你的$#prompt响应延迟高达2.4秒?权威调优白皮书首次公开
  • Cursor移动端适配实战手册(2024最新RN+Flutter双框架兼容白皮书)
  • 深入解析EDMA_TPTC:命令分段与TR流水线机制及性能调优实战
  • BlockLauncher脚本管理器架构剖析:JavaScript与C++游戏引擎的深度集成
  • 如何使用Formsmd创建交互式表单:从安装到部署的完整指南
  • USBIP-Win:企业级USB设备网络共享解决方案,实现跨平台远程设备管理
  • 2026年7月最新酒店帐篷厂家推荐榜单TOP5雅奢领衔盘点 - 优企名品
  • React-PDF视觉优化指南:5个技巧打造专业级PDF文档
  • Product Hunt 每日热榜 | 2026-07-17
  • Windows 11优化指南:5步让你的电脑告别臃肿,重获流畅体验