在C++中,二叉树非递归遍历是一种常用的算法,可避免递归过程中的系统开销和栈溢出问题。非递归遍历算法利用栈数据结构实现,可以实现前序、中序和后序遍历,是C++程序员必备技能之一
一、二叉树的前序遍历
题目链接
我们可以把任何一棵树看成左路节点,左路节点和右子树。先访问左路节点,再访问左路节点的右子树。在右子树中也重复这种循环,就是非递归遍历二叉树的思想。
解释:
栈st存放节点,v存放数值,cur初始化为root。
循环条件是栈不为空或者cur不为空(访问最后一个节点之前栈就已经为空了),循环遍历左子树并且把左子树入栈,同时把值存入v中。然后弹出栈顶元素,并且把栈顶元素的右子树赋值给cur,这样就形成了遍历。
当栈不为空的时候说明还有左路节点的右子树没有被访问,当cur不为空的时候说明还有树要被访问。当同时为空的时候才是访问完成。当一个节点出栈的时候说明此时该节点及该节点的左子树已经被访问完成了。
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> v;
TreeNode* cur = root;
while(cur || !st.empty())
{
while(cur)
{
st.push(cur);
v.push_back(cur->val);
cur = cur->left;
}
TreeNode* node = st.top();
st.pop();
cur = node->right;// 转化成子问题访问右子树
}
return v;
}
};
二、二叉树的中序遍历
题目链接
因为中序遍历的访问顺序是左根右,跟前序遍历不同,所以我们让左节点入栈的时候先不访问,出栈(说明左子树访问完了)时在访问节点。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur = root;
while(!st.empty() || cur)
{
while(cur)
{
st.push(cur);
cur = cur->left;
}
TreeNode* node = st.top();
st.pop();
v.push_back(node->val);
cur = node->right;
}
return v;
}
};
三、二叉树的后序遍历
3.1 方法一
首先我们知道后序遍历就是左右根,而我们可以把访问顺序变成根右左,然后再逆置顺序。而根右左就跟前序遍历的方法一样:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> v;
TreeNode* cur = root;
while(cur || !st.empty())
{
while(cur)
{
st.push(cur);
v.push_back(cur->val);
cur = cur->right;
}
TreeNode* node = st.top();
st.pop();
cur = node->left;
}
reverse(v.begin(), v.end());
return v;
}
};
3.2 方法二
按照常规的遍历方法走左右根,但是这里有一个问题:
当访问到根的时候有两种情况:
1️⃣ 从左子树回来,现在要先访问右子树
2️⃣ 从右子树回来,左右子树已经访问完毕,再访问根。
针对这种情况我们可以在加一个变量来确定是第几次访问根,如果是第一次就访问右子树,如果是第二次就访问。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<pair<TreeNode*, bool>> st;
vector<int> v;
TreeNode* cur = root;
while(cur || !st.empty())
{
while(cur)
{
st.push(make_pair(cur, false));
cur = cur->left;
}
TreeNode* node = st.top().first;
if(st.top().second == true)
{
st.pop();
v.push_back(node->val);
}
else
{
st.top().second = true;
cur = node->right;
}
}
return v;
}
};
到此这篇关于C++实现二叉树非递归遍历算法详解的文章就介绍到这了,更多相关C++二叉树非递归遍历内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:C++实现二叉树非递归遍历算法详解
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30
- ubuntu下C/C++获取剩余内存 2023-09-18
- Easyx实现扫雷游戏 2023-02-06
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- C语言详解float类型在内存中的存储方式 2023-03-27
- Qt计时器使用方法详解 2023-05-30
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- C语言qsort()函数的使用方法详解 2023-04-26
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- C++ 数据结构超详细讲解顺序表 2023-03-25
