二叉树的中序&后序遍历——非递归版本
创作时间:
作者:
@小白创作中心
二叉树的中序&后序遍历——非递归版本
引用
CSDN
1.
https://m.blog.csdn.net/2301_80689220/article/details/142718189
二叉树的遍历是数据结构中的一个重要知识点,其中中序遍历和后序遍历是两种常见的遍历方式。本文将详细介绍这两种遍历方式的非递归实现方法,帮助读者更好地理解二叉树的遍历过程。
1.题目解析
题目来源:二叉树的中序遍历——力扣
测试用例
题目来源:二叉树的后序遍历——力扣
测试用例
2.算法原理
中序遍历
中序遍历:左子树->根节点->右子树
与之前前序遍历的思路基本相同,不过需要注意的是中序变量需要在遍历完左子树后才可以访问根节点,也就是首先将左子树入栈,入栈完成后取出栈顶结点再访问该节点,这样就可以达到先访问左子树再访问根节点再访问右子树的效果
后序遍历
后序遍历:左子树->右子树->根节点
后序遍历属于三个遍历中最难的一种,因为我们需要先遍历左子树再遍历右子树后才能访问根节点,这并不是简单的将前序遍历逆置就可以得到的,首先我们有以下的困难:
1. 当访问一个节点首先将其左子树入栈后如何将其右子树入栈后再访问根节点
2.如何判断是否需要访问一个节点的右子树才能避免重复访问
3.如何控制入栈的顺序
解决方法:
1.首先我们从一棵树的根节点开始,不断向栈内插入左节点直到左边无可插入元素,此时处理栈顶元素,我们首先要判断此元素是否有右子树,有则需要入栈,反之没有则访问该节点的上一个级节点,这里判断的方法是创建一个prev保留待判断节点的栈内上一个元素,如果该元素是待判断元素的右节点则代表待判断元素的左右子树均已遍历,直接访问该节点即可
2.如果prev不是待判断元素的上一个节点则表示此时待判断节点的右子树还没有遍历,需要访问其右子树,所以将栈顶元素的右节点放入循环即可
3.实战代码
中序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur = root;
while(cur || !st.empty())
{
//只入栈根节点而不访问
while(cur)
{
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
st.pop();
//在左子树访问完毕之后再访问根节点
//以达到左子树->根节点->右子树的顺序
v.push_back(top->val);
cur = top->right;
}
return v;
}
};
后序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
TreeNode* prev = nullptr;
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中后在栈中删除该元素,并且将该节点更新为prev节点
if(top->right == nullptr || top->right == prev)
{
v.push_back(top->val);
st.pop();
prev = top;
}
//如果没有访问过说明只是访问了之前节点的左子树
//需要先访问右子树再访问该节点
else
{
cur = top->right;
}
}
return v;
}
};
热门推荐
如何评估家庭资产的状况?这种资产评估的方法有哪些?
项目经理如何处理债务问题?20种解决方案全解析
如何调整证券账户的佣金费率?这种调整对投资成本有什么影响?
充电功率忽高忽低对电池有影响吗?
什么是高温锂电池?原理、优势与应用领域全解析
掌握起诉三个关键步骤,轻松实现法律维权
农民工怎样防止拖欠工资
民族体育项目知多少——民族武术
胃食管反流,中医如何防治与养护
欧冠前瞻:马竞vs皇马,银河战舰客场能否延续优势?
心房颤动治疗:2024国际专家共识解读
提升云直播在线教学中师生互动的有效策略
缩量时代的营销革命:三大方向破解存量市场困局,五大方法引领品牌重生
中国光电医美行业:市场规模将破千亿,2024-2031年持续高速增长
运动科学帮助你轻松实现新年健身目标
如何判断租房小区是否有光纤,自己也能安装
简单了解雪茄和香烟的原材料和制作过程
速度与安全的天平:探究汽车速度与刹车系统之间的关系
古道、茶园、山野……去安吉享受一次绿色之旅
普洱茶红票蓝票的含义解读
法院继承房产如何调解
“轨道上的长三角”建设加快推进 今年建设投资预计超1300亿元
可用于高质量回测的 MetaTrader 历史数据导入及转换教程
工作流程用excel怎么做
25-羟基维生素 D 检测的 4 大临床意义——最新解读
腰部热身运动有哪些?便宜的自发热护腰带有害
黄芪提取物在增强免疫力方面的研究进展
黄芪粉的功效与作用及食用方法是什么
白切肉的制作步骤
燃油车的智能化转型:“全民智驾”时代如何突出重围?