二叉树前序中序后序遍历(非递归)

大家好,又和大家见面啦!今天我们一起去看一下二叉树的前序中序后序的遍历,相信这个对大家来说是信手拈来,但是,今天我们并不是使用常见的递归方式来解题,我们采用迭代方式解答。我们先看第一道前序遍历 

1、前序遍历

二叉树的前序遍历

前序遍历是先将二叉树的根节点遍历,再遍历左子树、右子树。我们做这道题的思想是把二叉树划分为两部分,一是左路节点,二是左路节点的右子树。什么是左路节点,如上图的二叉树来说,

这就算以8为根节点的二叉树的左路节点,也就是以8为根节点,它的左孩子的左孩子的左孩子......这一条路径。我们先让左路节点入栈,因为是前序遍历,所以我们入栈的同时,遍历当前结点的val,当左路结点都入栈完,那么当前节点一定是没有左子树的,我们让这个结点出栈,这个时候我们处理当前结点的右子树,右子树同样进行先让左路节点入栈.....循环做此操作,直到右子树也会空,然后将这个结点的所有左右子树我们都访问完成,我们已经pop掉这个时候,只需要处理新的栈顶元素就可以啦。

话不多说,思路就是这个样子,下面把代码写出来让大家看看。

定义一个cur从根节点开始,然后定义一个栈存储左路结点,一个vector存储左路节点的数据。

vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;TreeNode* cur=root;//cur从根节点开始while(cur){while(cur){v.push_back(cur->val);st.push(cur);//左路结点入栈cur=cur->left;}//处理栈内的右子树TreeNode* top=st.top();st.pop();cur=top->right;//处理左路节点的右子树}return v;}

代码写起来很简单,但是我们会发现这个提交是过不了的,为什么呢?大家看,我们在把1的右节点赋给cur去处理1的右子树时,结点1是没有右结点的,这个时候cur为空,上面这个大循环就进不去,而这个时候,我们其它的左路节点都还在栈里面没有处理,所以,外面这个大循环的判断条件是不正确的。应该改成

while(cur||!st.empty())

当栈不为空的时候,我们也要处理。 然后我们再运行,就可以通过了。

2、中序遍历

二叉树的中序遍历

我们还是拿这棵树来看,其实中序和前序思路是完全一样,只不过前序的遍历顺序是根左右,我们左路结点入栈的时候就可以直接访问其val,但是中序遍历的顺序是左根右,所以我们写中序的时候应该把访问val的顺序调到结点出栈的时候访问就可啦。

下面我们开始实现

vector<int> inorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;TreeNode* cur=root;while(cur||!st.empty()){while(cur)//左路结点进栈{st.push(cur);cur=cur->left;}TreeNode* top=st.top();v.push_back(top->val);st.pop();cur=top->right;//处理当前结点的右子树}return v;}

3、后序遍历

二叉树的后序遍历

后序遍历的遍历顺序是左右根,我们只有把左右结点全部访问完成才能访问根节点的数据,或者左右节点为空才能直接访问根节点的数据。左节点我们在左路子树入栈的时候就算是访问,但是右节点怎么解决呢?

所以说,我们这里需要解决一下,怎么才能知道右节点已经访问过了。我们以这里的结点6为例,要访问结点6的val,首先,我们把8,3,1入栈,结点1没有右子树,可以直接获取它的val,出栈后,栈顶元素是3,3有右子树,需要先处理它的右树,,然后6,4入栈,这时栈顶结点为4,4没有右树,直接获取它的val,此时栈顶元素为6,6他有右树,需要先处理他的右树,此时结点7入栈,这个时候7没有右树,直接获取它的val,这个时候结点6的左右树都访问完毕,可以访问6的val了,但是我们怎么判断结点6的左右树都已经访问完毕了呢?结点6上一次访问的结点是7,我们只需要判断,6结点的上一次访问的结点是不是7就可以了。

我们可以定义一个结点prev,每访问完一个栈顶元素,我们就把top赋给prev,表示上一个访问结点,我们只需要判断top->right==prev,即我们已经访问过top->right这个结点就行了,这样我们可以直接获取栈顶的val值。

因此,只有在当前结点的右树为空,或者当前结点的右结点是我们上一次访问的结点,我们就可以获取它的val值。

下面我们开始写代码

vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;TreeNode* cur=root;TreeNode* prev=nullptr;while(cur||!st.empty()){while(cur){st.push(cur);cur=cur->left;}TreeNode* top=st.top();//分情况讨论,如果当前这个结点的右子树为空,或者当前结点的右子树是我们上次访问的结点;表示我们已经访问过它的子树,就可以直接获取当前结点的valif(top->right==nullptr||top->right==prev){st.pop();v.push_back(top->val);prev=top;}//否者,访问这个结点的右树else{cur=top->right;}}return v;

到这里,二叉树的前序中序后序三个非递归方式就讲解完毕啦。我们下次再见呀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CCF编程能力等级认证GESP—C++6级—20231209

CCF编程能力等级认证GESP—C6级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)闯关游戏工作沟通 答案及解析单选题判断题编程题1编程题2 单选题…

js中数字精度丢失问题详解(如何解决)

文章目录 一、场景复现二、浮点数三、问题分析小结 四、解决方案参考文献 一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333...... 3会一直无限循环&#xff0c;数学可以表示&#xff0c;但是计算机要存…

mysql 2-17

UNION关键字和UNION ALL 自然连接 USING使用 函数 单行函数 基本函数 三角函数 指数和对数 进制间的转换 字符串函数 时间和日期函数 计算日期和时间的函数 日期的格式化和解析 流程控制函数

《剑指 Offer》专项突破版 - 面试题 47 : 二叉树剪枝(C++ 实现)

题目链接&#xff1a;LCR 047. 二叉树剪枝 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 一棵二叉树的所有节点的值要么是 0 要么是 1&#xff0c;请剪除该二叉树中所有节点的值全都是 0 的子树。例如&#xff0c;在剪除下图 (a) 中二叉树中所有节点值都为 0 的…

【NI-DAQmx入门】处理数据采集和测试系统中噪声的几种主要方法

在实际的测试系统中测量模拟信号并不总是像将信号源连接到测量设备那么简单。数据完整性取决于被控制和监视的电气设备发送和接收的干净的电信号。 电噪声可能会掩盖电信号并使其无法识别&#xff0c;从而损害原本具备功能的 DAQ 系统。数据采集​​是关键任务应用测试系统的一…

C++模板详解 —— 函数模板与类模板

C模板详解 泛型编程函数模板函数模板的概念函数模板的原理 函数模板的实例化函数模板的匹配原则类模板类模板的定义格式类模板的实例化 泛型编程 如果让你编写一个函数&#xff0c;用于两个数的交换。在C语言中&#xff0c;我们会用如下方法&#xff1a; void Swapi(int* p1,…

在PyTorch中,如何查看深度学习模型的每一层结构?

这里写目录标题 1. 使用print(model)2. 使用torchsummary库3.其余方法&#xff08;可以参考&#xff09; 在PyTorch中&#xff0c;如果想查看深度学习模型的每一层结构&#xff0c;可以使用print(model)或者model.summary()&#xff08;如果你使用的是torchsummary库&#xff0…

2024.2.17每日一题

LeetCode N 叉树的层序遍历 429. N 叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点…

机试复习-4

1.string类 string类型和数值的转换 ※数值→字符串 to_string函数 //具体做法 int i1234; string gto_string(i);//这样就转成字符串1234了 //下面就是字符串转为数字&#xff0c;类似下面还有stof,stoi,stod string d "1289347647"; int j stoi(d); cout <…

线索化二叉树(先序,中序,后序)+线索化二叉树的遍历【java详解】

目录 线索化二叉树的基本介绍&#xff1a; 举个栗子&#xff1a; 二叉树的中序线索化&#xff1a; 创建HeroNode类&#xff0c;表示节点信息&#xff1a; 编写中序线索化方法代码&#xff1a; 中序线索化遍历代码&#xff1a; 测试代码&#xff1a; 测试结果&#xff1a…

OpenHarmony系统解决方案 - 配置屏幕方向导致开机动画和Launcher显示异常

问题环境 系统版本&#xff1a;OpenHarmony-3.2-Release 问题现象 配置设备默认方向&#xff0c;例如修改为横屏显示&#xff0c;修改文件display_manager_config.xml的buildInDefaultOrientation参数值为2(Orientation::HORIZONTAL)。 源码中文件位于foundation/window/win…

在 Geoserver 中添加自定义的室内坐标系

要在 Geoserver 中添加自定义的室内坐标系&#xff0c;您需要在数据目录中的 user_projections 文件夹下创建或编辑一个 epsg.properties 文件&#xff0c;然后在文件末尾添加您的坐标系的定义&#xff0c;使用 WKT&#xff08;Well-Known Text&#xff09;格式。您还需要为您的…

WordPress站点成功升级后的介绍页地址是什么?

我们一般在WordPress站点后台 >> 仪表盘 >> 更新中成功升级WordPress的话&#xff0c;最后打开的就是升级之后的版本介绍页。比如boke112百科前两天升级到WordPress 6.4.2后显示的介绍页如下图所示&#xff1a; 该介绍除了介绍当前版本修复了多少个问题及修补了多少…

ABC341 A-G

Toyota Programming Contest 2024#2&#xff08;AtCoder Beginner Contest 341&#xff09; - AtCoder B读不懂题卡了&#xff0c;F读假题卡了&#xff0c;开题开慢了rank了 A - Print 341 题意&#xff1a; 打印一串交替出现的包含N个0&#xff0c;N1个1的01串 代码&…

2024免费人像摄影后期处理工具Portraiture4.1

Portraiture作为一款智能磨皮插件&#xff0c;确实为Photoshop和Lightroom用户带来了极大的便利。通过其先进的人工智能算法&#xff0c;它能够自动识别并处理照片中的人物皮肤、头发和眉毛等部位&#xff0c;实现一键式的磨皮美化效果&#xff0c;极大地简化了后期处理的过程。…

Switch开关(antd-design组件库)简单使用

1.Switch开关 开关选择器。 2.何时使用 需要表示开关状态/两种状态之间的切换时&#xff1b; 和 checkbox 的区别是&#xff0c;切换 switch 会直接触发状态改变&#xff0c;而 checkbox 一般用于状态标记&#xff0c;需要和提交操作配合。 组件代码来自&#xff1a; 开关 Swit…

【leetcode题解C++】51.N皇后 and 76.最小覆盖子串

51. N皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方…

用Python和OpenCV搭建自己的一维码和QRCode扫描仪(步骤 + 源码)

导 读 本文主要介绍使用Python和OpenCV搭建自己的一维码和QRCode扫描仪&#xff08;步骤 源码&#xff09;。 项目简介 本文我们将创建一个程序来扫描图像中的二维码和条形码。对于这个程序&#xff0c;我们需要三个包&#xff0c;分别是OpenCV、NumPy和pyzbar。大多数 Pyth…

linux kernel 内存踩踏之KASAN_HW_TAGS(MTE)(三)

一、背景 linux kernel 内存踩踏之KASAN&#xff08;一&#xff09;_kasan版本跟hasan版本区别-CSDN博客 linux kernel 内存踩踏之KASAN_SW_TAGS&#xff08;二&#xff09;-CSDN博客 最后来介绍一下KASAN_HW_TAGS&#xff0c;ARM64上就是MTE&#xff0c;这个特性在ARMv8.5支…

C++数据结构与算法——栈与队列

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…