news 2026/7/4 18:39:13

【二叉树】DFS遍历的迭代理解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【二叉树】DFS遍历的迭代理解

我们知道,二叉树前中后序遍历的常见写法是递归,而递归的底层逻辑是栈,所以理论上来说,所有递归都能用栈来实现,只是复杂的递归用栈实现起来会很复杂
而这种简单的递归,不仅用栈实现不是很复杂,还涉及到了递归的底层逻辑的理解,是面试很喜欢的题目
现在和我一起走进它吧


如果我们想得到遍历结果,肯定是以某种顺序将节点压入栈中,以某种顺序弹出节点,而弹出节点的顺序就是遍历的结果(出栈的顺序就是遍历结果的顺序)
所以我们要解决的问题就是上方提到的两个某种顺序

先说结论:
前序遍历:结果需要以中左右弹出栈,所以 以中右左的顺序入栈
后序遍历:修改前序遍历的代码两处
中序遍历:用指针记录遍历顺序,到某种程度出栈


前序遍历:

我们知道前序遍历的顺序是中->左->右
举个例子:

5 / \ 4 6 / \ 1 2

遍历结果为54126
它具有一个特点:即时性(访问这个元素,就直接输出,再进行下一步)

class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> res; stack<int> st; if(root==nullptr) return nullptr; st.push(root->val); while(root){ if(root->right) st.push(root->right->val); if(root->left) st.push(rott->left->val); } return res; } };

后序遍历:

后序遍历的顺序是左->右->中
所以从前序到后序只需要修改两步:中左右->中右左->左右中

  • 第一步:将左右的访问顺序对调
  • 第二步:将结果数组存储的结果倒序输出
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*> st; vector<int> v; if(root!=nullptr) st.push(root); while(!st.empty()){ TreeNode*topNode=st.top(); st.pop(); v.push_back(topNode->val); if(topNode->left!=nullptr){ st.push(topNode->left); } if(topNode->right!=nullptr){ st.push(topNode->right); } } reverse(v.begin(),v.end()); return v; } };

中序遍历:

后序遍历的顺序是左->中->右
它是特殊的,因为它与我上方说的即时性相反,具有延后性
(访问到这个元素,需要等到它的左子树访问到的时候,才能输出这个元素)
所以我们需要一个指针来记录遍历顺序,当左为空,就弹出该节点;右为空,说明是叶子结点,弹出该节点的父节点

class Solution { public: vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*> st; vector<int> v; TreeNode*p=root; while(p!=nullptr||!st.empty()){ if(p!=nullptr){ st.push(p); p=p->left; } else{ p=st.top(); st.pop(); v.push_back(p->val); p=p->right; } } return v; } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 12:24:52

[GWCTF 2019]枯燥的抽奖

启动环境 检查发现源码 通过查找mt_rand函数资料&#xff0c;PHP的mt_rand函数作为一个随机数生成工具在程序中被广泛使用&#xff0c;但是大家都忽略了一个事实&#xff0c;mt_rand生成的随机数不是一个真正的随机数&#xff0c;而是一个伪随机数&#xff0c;不能应用于生成安…

作者头像 李华
网站建设 2026/7/2 2:27:36

54、内存映射文件I/O与Solaris 64位文件支持详解

内存映射文件I/O与Solaris 64位文件支持详解 1. 异步I/O与内存映射文件I/O概述 在文件I/O操作中,传统的方式是通过 read 、 write 和 lseek 系统调用来为进程执行I/O,并在进程的地址空间和内核缓冲区之间复制数据。例如,使用 read(2) 系统调用进行文件读取时,数据…

作者头像 李华
网站建设 2026/6/30 21:23:41

58、深入探究文件系统框架与I/O操作

深入探究文件系统框架与I/O操作 1. 块I/O与vnode页面 块I/O子系统支持对vnode页面进行I/O操作。以下三个函数可用于在物理页面和设备之间发起I/O: | 函数 | 描述 | | — | — | | bdev_strategy() | 使用块I/O设备在页面上发起I/O | | pageio_done() | 等待块设备I/O完成…

作者头像 李华
网站建设 2026/6/30 9:46:16

61、Unix文件系统UFS实现解析

Unix文件系统UFS实现解析 1. UFS概述 UFS(Unix文件系统)被实现为一个可加载的文件系统模块,包含vfs和vnode对象的实例。其中,UFS的vnode接口实现文件操作,而UFS的vfs接口则实现文件系统管理。 UFS文件系统的实现主要分为以下五个部分: - 一个vfs对象实例,以及用于挂…

作者头像 李华
网站建设 2026/7/2 18:51:15

62、Solaris文件系统缓存:原理、优化与性能分析

Solaris文件系统缓存:原理、优化与性能分析 在操作系统中,文件系统缓存是提升文件读写性能的关键机制。本文将深入探讨Solaris系统中文件系统缓存的工作原理、优化策略以及对系统性能的影响。 1. 文件缓存简介 文件系统的一个重要特性是能够缓存文件数据。然而,在Solaris…

作者头像 李华
网站建设 2026/7/3 20:37:54

Qwen3-30B-A3B模型参数配置指南:解锁高效推理与流畅交互的双重体验

在大语言模型应用中&#xff0c;参数配置如同调节精密仪器的旋钮&#xff0c;微小的调整可能带来截然不同的输出效果。Qwen3-30B-A3B作为新一代大模型&#xff0c;凭借其300亿参数规模与A3B架构优化&#xff0c;在复杂推理与自然对话场景中均展现出卓越性能。本文将系统解析该模…

作者头像 李华