【C++二叉树】二叉树的前序遍历、中序遍历、后序遍历递归与非递归实现

1.二叉树的前序遍历

144. 二叉树的前序遍历 - 力扣(LeetCode)

前序遍历方式:根-左子树-右子树。

递归实现:

要传一个子函数来实先递归,原因是原函数返回值为vector,在原函数迭代,返回值就难处理了。

非递归(迭代)实现:

递归实现非常简单,非递归呢?

要用迭代实现,也就是循环:

还是按照根-左子树-右子树的遍历方式遍历。

遍历:先访问1、3、4再访问4的右子树再退回去访问3的右子树和1的右子树。

这时,我们可以把树分为左路节点和左路节点的右子树。

也就是先访问左路节点再访问左路节点的右子树,右子树也同样分为左路节点和左路节点的右子树。

这时,就要使用栈来解决:

  1. 把左路节点入栈,入栈的同时访问节点(遍历根),当左路节点为空时停止入栈,同时也证明左子树已经访问结束。
  2. 这时再访问左路节点的右子树。取栈顶数据(栈顶数据就是左路节点)的右子树,再把栈顶数据弹出。
  3. 右子树同样分为左路节点和左路节点的右子树,同样按照此方法迭代循环。
  4. 直到最后一个节点访问结束,此时,节点为空,栈为空。

自己根据代码,画一下图模拟迭代过程就容易理解了。

2.二叉树的中序遍历

94. 二叉树的中序遍历 - 力扣(LeetCode)

中序遍历方式:左子树-根-右子树。

递归实现:

非递归(迭代)实现:

中序遍历的非递归和前序遍历的非递归思路类似。

  1. 都是按照把树分为左路节点和左路节点的右子树的思路来实现的,只不过访问节点(根)的时机不同。
  2. 前序遍历是先访问根再访问左子树右子树,所以在左路节点入栈的时候,就访问节点(根),而中序遍历是先访问左子树再访问根再访问右子树
  3. 所以中序遍历是在左路节点入栈完以后,再访问节点(根)。

3.二叉树的后序遍历

145. 二叉树的后序遍历 - 力扣(LeetCode)

后序遍历方式:左子树-右子树-根

递归实现:

非递归迭代实现:

后序遍历方式:左子树-右子树-根

后序遍历的非递归与前序和中序的非递归整体思路类似。

唯一不同的就是访问节点的时机不同。

什么时候访问节点(根)呢?

  1. 从栈中取出左路节点时,节点的左子树已经访问完了(理解理解)。
  2. 当左路节点的右子树访问完才可以访问根。
  3. 如果左路节点的右子树为空,则代表右子树访问完,可以访问节点(根)了。
  4. 如果右子树不为空,则要先访问左路节点的右子树。

非递归迭代实现:

但是此时会发现超出了内存限制,说明代码有问题,内存限制问题一般就是死循环了。

按照上面的代码,会发现,节点3和节点5之间会一直死循环,

  1. 3的右子树不为空,把5入栈,5的右子树为空,把栈中5弹出来,下次循环又取了栈顶数据3,3的右子树不为空,把5入栈......
  2. 第二次访问节点3的时候,就应该直接访问节点(根)了,但他的右子树不为空,又访问了右子树,他不知道右子树已经访问过了,就会不断的进入3的右子树访问就死循环了。

所以,关键问题就说我们要想一个办法区分他的右子树到底访问过了没有,如果访问过了,则可以访问该左路节点(根)了,如果没有访问,则先访问他的右子树。

此时,可以使用双指针来解决,我们定义一个指针lastNode表示当前节点的上一个节点。

访问节点3的时候,lastNode为右子树的根(节点5),代表右子树已经访问完了,则就可以访问该节点了。

非递归(迭代)实现:

4.总结:

  • 前序遍历、中序遍历、后序遍历的递归实现很简单,但是非递归迭代实现就有稍微有点难理解了。
  • 用了同一种思路,把树分为左路节点和左路节点的右子树,针对这三种遍历方式都适用。
  • 从根本上就是用循环模拟递归的过程。
  • 后序遍历相对前序和中序又稍微复杂,要考虑好访问节点的条件,避免死循环。
  • 多画图模拟迭代的过程更容易理解。
相关推荐
西瓜本瓜@4 分钟前
在Android中fragment的生命周期
android·开发语言·android studio·kt
Che3rry7 分钟前
C/C++|关于多线程冲突
java·c语言·c++
DA树聚14 分钟前
Transformer模型-7- Decoder
人工智能·深度学习·神经网络·算法·目标检测·语言模型·transformer
优联前端15 分钟前
uni-app-通过vue-cli命令行快速上手
开发语言·前端·vue.js·uni-app·优联前端
老半撅儿32 分钟前
Python基础 | 在虚拟环境中安装并在指定文件夹中打开Jupyter notebook
开发语言·python·jupyter
pumpkin8451433 分钟前
SIP Servlets学习
开发语言·学习
卑微的Coder1 小时前
python画正方形、平行四边形、六边形、五角星、风车(四个半圆)
开发语言·python
bugtraq20211 小时前
Fyne ( go跨平台GUI )中文文档-绘图和动画(三)
开发语言·后端·golang
L_cl2 小时前
数据结构与算法——Java实现 7.习题——反转链表
java·开发语言·链表
明志刘明2 小时前
昇思量子计算系列教程-龙算法
深度学习·算法·量子计算