数据结构:二叉树的非递归遍历

前言

在前面我们学习了二叉树的递归遍历,但是,众所周知,递归是比较消耗资源的,所以,在有些注重性能的地方,会需要使用到非递归遍历,在这里介绍一下,二叉树的非递归遍历。

本质上:二叉树的非递归遍历也是模拟递归遍历,递归遍历中需要产生深层次的函数栈帧,而非递归就是将这些深层次的函数栈帧存起来模拟递归。

前序遍历

前序遍历的遍历顺序是:根 + 左子树 + 右子树

我们将其转化为非递归,就在于

  1. 先访问左路节点
  2. 在访问左路节点的右子树

也就是我们采用栈的数据结构,

在每一次访问左路节点的时候将其入栈

左路节点访问完之后,开始取栈顶元素,去访问其右子树,

-----此图借鉴于csdn博主"想写好代码的小猫头"

按照先序遍历的思路,栈里面的过程如下:

C++ 复制代码
void prevOrder(Node* root)
{
	stack<Node*> s;
	Node* cur = root;

	while (cur || !s.empty())
	{
		while (cur)
		{
			cout << cur->_data << " ";
			s.push(cur);

			cur = cur->_left;
		}

		Node* top = s.top();
		s.pop();
		cur = top->_right;
	}
}

中序遍历

中序遍历的顺序是:左子树 + 根 + 右子树

我们将其转化为非递归,其实和前序遍历非常像,只是在于,访问根节点的时间不同了

前序遍历是每次遇到新节点的时候就直接访问新节点,

而中序遍历则是在访问完左路节点之后,开始访问根节点(也就是左路节点全部入栈之后才访问根节点)

直接写代码吧

C++ 复制代码
void inOrder(Node* root)
{
	stack<Node*> s;
	Node* cur = root;

	while (cur || !s.empty())
	{
		while (cur)
		{
			s.push(cur);
			cur = cur->_left;
		}

		Node* top = s.top();
		s.pop();
		cout << top->_data << " ";
		cur = top->_right;
	}
}

后序遍历

后序遍历相较于前两种遍历麻烦一点,但也很简单

后序遍历的难点在于,当访问到一个节点的时候,我们需要知道这个节点的右子树有没有访问,

如果没有访问,就要先访问右子树,否则才能访问自己。

解决这个问题有两个办法

  1. 使用一个flag来标记,右子树有没有被访问,但是控制起来有点麻烦
  2. 下面详细说一下这种办法,比较巧妙

方法二:

当我们访问到一个节点的时候,我们可以记录下前一个访问的节点

如果前一个访问的节点是该节点的右子节点,说明该节点的右子树访问完了(后序遍历,左子树 右子树 根)

如果前一个访问的节点不是该节点的右子节点,说明该节点的右子树没有访问完,需要访问右子树

代码

C++ 复制代码
void postOrder(Node* root)
{
	stack<Node*> s;

	Node* cur = root;
	Node* prev = nullptr;

	while (cur || !s.empty())
	{
		while (cur)
		{
			s.push(cur);
			cur = cur->_left;
		}

		Node* top = s.top();

		if (prev == top->_right || top->_right == nullptr)
		{
			cout << top->_data << "";
			prev = top;
			s.pop();
		}
		else
		{
			cur = top->_right;
		}
	}
}
相关推荐
宵时待雨11 小时前
优选算法专题9:哈希表
数据结构·算法·散列表
txzrxz11 小时前
最短路问题——Dijkstra 算法
数据结构·c++·算法·最短路·优先队列
noipp12 小时前
推荐题目:洛谷 P6231 [JSOI2013] 公交系统
c语言·数据结构·c++·算法·游戏·洛谷·luogu
青山木18 小时前
Hot 100 ---腐烂的橘子
java·数据结构·后端·算法·leetcode·广度优先
未来之窗软件服务18 小时前
计算机考试-快速排序—东方仙盟
数据结构·算法·排序算法·仙盟创梦ide·东方仙盟
小龙报18 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
wWYy.18 小时前
数据结构:跳表
数据结构
变量未定义~19 小时前
虚拟节点-星石传送阵(4星)、强连通分量
数据结构·算法
电子云与长程纠缠20 小时前
UE中使用TGuardValue与TInlineComponentArray数据结构
开发语言·数据结构·学习·ue5·游戏引擎
自由随风飘21 小时前
JAVA中的面向对象-2
java·开发语言·数据结构