二叉树的前序、中序、后序遍历 -- 非递归方式实现

目录

前序遍历:根 左 右

实现思想:

需要创建一个栈和一个vector容器

栈用来保存最左路径的节点

vector用来保存遍历的数据

1.首先用一个while循环将二叉树的最左路径节点全部压入栈内,同时由于前序遍历的特性,也将该节点的值同时压入vector容器内

2.循环完成后,栈顶元素为二叉树的最左节点。将该节点获取为当前节点后,对栈顶元素进行移除。

3.访问当前节点的右子树。

4.重复循环,直到当前节点为空,或者栈为空。

实现过程:

cpp 复制代码
class Solution
{
public:
	//前序遍历:根 左 右(非递归)
	vector<int> preorderTraversal(TreeNode* root)
	{
		stack<TreeNode*> st;
		vector<int> vec;
		TreeNode* cur = root;
		while (cur || !st.empty())
		{
			while (cur)
			{
				//将二叉树最左路径压入栈内
				st.push(cur);
				//将最左节点的值压入vector内
				vec.push_back(cur->val);
				cur = cur->left;
			}
			//获取最左节点
			cur = st.top();
			//将最左节点从栈内移除
			st.pop();

			//访问右子树
			cur = cur->right;
		}
		return vec;
	}
};

中序遍历:左 根 右

实现思想:

和前序遍历十分类似,不同之处在于将节点值压入vector的位置不一样。

前序遍历是在将二叉树最左路径节点压入栈的同时,也将该节点的值压入vector。

但是中序遍历是要先从最左节点开始进行,因此将节点值压入vector的操作换到第二步完成。

创建一个栈和一个vector容器

栈用来保存最左路径的节点

vector用来保存遍历的数据

1.首先用一个while循环将二叉树的最左路径节点全部压入栈内。

2.循环完成后,栈顶元素为二叉树的最左节点。将该节点获取为当前节点后,对栈顶元素进行移除,并将该节点的值压入vector容器

3.访问当前节点的右子树。

4.重复循环,直到当前节点为空,或者栈为空。

实现过程:

cpp 复制代码
class Solution
{
public:
	//中序遍历:左 根 右(非递归)
	vector<int> inorderTraversal(TreeNode* root)
	{
		stack<TreeNode*> st;
		vector<int> vec;
		TreeNode* cur = root;
		while (cur || !st.empty())
		{
			while (cur)
			{
				//将二叉树最左路径压入栈内
				st.push(cur);
				cur = cur->left;
			}
			//获取最左节点
			cur = st.top();
			//将最左节点从栈内移除
			st.pop();
			//将最左节点的值压入vector内
			vec.push_back(cur->val);

			//访问右子树
			cur = cur->right;
		}
		return vec;
	}
};

后序遍历:左 右 根

实现思想:

创建一个栈和一个vector容器

栈用来保存最左路径的节点

vector用来保存遍历的数据

创建两个指针

一个指向当前节点、一个指向上一栈顶节点

1.首先用一个while循环将二叉树的最左路径节点全部压入栈内。

2.循环完成后,栈顶元素为二叉树的最左节点。将栈顶元素获取为top节点。

3.判断top节点是否可以压入vector,条件为top节点的右子树为空,或者top节点的右子树已经被压入vector。满足条件后将该top节点压入vector,同时将prev更新。

3.如果不满足条件,则访问top节点的右子树。

4.重复循环,直到当前节点为空,或者栈为空。

实现过程:

cpp 复制代码
class Solution
{
public:
	//后序遍历:左 右 根(非递归)
	vector<int> postorderTraversal(TreeNode* root)
	{
		stack<TreeNode*> st;
		TreeNode* cur = root;
		TreeNode* prev;
		vector<int> vec;
		while (cur || !st.empty())
		{
			while (cur)
			{
				st.push(cur);
				cur = cur->left;
			}
			//获取栈顶元素
			TreeNode* top = st.top();
			//判断当前的节点是否可以遍历
			if (top->right == nullptr || top->right == prev)
			{
				vec.push_back(top->val);
				st.pop();
				prev = top;
			}
			else
				//访问右子树
				cur = top->right;
		}
		return vec;
	}
};
相关推荐
大数据追光猿16 分钟前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!33 分钟前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉34 分钟前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生34 分钟前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴39 分钟前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing39 分钟前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财39 分钟前
加油站(力扣134)
算法·leetcode·职场和发展
王老师青少年编程40 分钟前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛
qy发大财41 分钟前
柠檬水找零(力扣860)
算法·leetcode·职场和发展
瓦力的狗腿子43 分钟前
Starlink卫星动力学系统仿真建模番外篇6-地球敏感器
算法·数学建模·simulink