当前位置:网站首页>二叉树非递归遍历
二叉树非递归遍历
2022-07-31 21:33:00 【Massachusetts_11】
1. 遍历一棵树
前、中、后序遍历的路径实际是相同的,都是以如上路径去游历。
前、中、后序访问的结果不同,实际是访问节点的时机不同:
前序:一遇到节点就去访问
中序:访问完左树再去访问
后序:访问完右子树再去访问
如下是B节点的前、中、后序访问时机
2. 非递归遍历
2.1 理解
之前的递归遍历,将一棵树看成一个对称结构:左子树
根右子树
,借助递归函数,可以进入左右子树进行访问;
但如果想在当前函数内进行迭代访问,之前的左右子问题的方式就很难实现了。
这里我们不妨再看看这个遍历的路径图:
首先沿着最左侧向下走过A-B-D
然后向上,走D的右子树、B的右子树、A的右子树,走完A的右子树回来就代表遍历结束了
这里访问右子树就可以看成是一个子问题——访问以右节点为根的另一棵树,重新回到最一开始;
可以发现左侧节点第一次走到的顺序是从上至下:A-B-D
,下一次遇到访问右子树的顺序又是D-B-A
,恰好相反,因此可以用栈的结构,从左侧走的时候先把节点依次从上至下存起来,当遍历到底,遇到空的时候再取出栈顶的节点,通过这个节点去访问它的右树;
同时凭借着栈的结构,当进入右树,走到右树的节点,依然入此栈,当右树走完回来,右树所有入栈的节点也都已经取出,又只剩下了之前主干上的节点,还可继续主线逻辑,与递归方式的逻辑相似——不管递归出去的逻辑多复杂,完成了分支任务回来,我的主线任务还要正常进行。
2.2 实现
注:以下只提供了非递归游历整棵树的方法,前、中、后序访问节点的时机未写入,具体见后。
变量定义:
实现:
遍历最左侧节点,同时将他们依次入栈
开始取栈中元素
通过此节点访问它的右树
遍历结束的判断
- 栈中元素取完——栈空
- 同时当前的根节点对应一棵空树
子树为空的情况(返回主干问题):
跳过当前树的遍历,从栈中取下一个节点
当前逻辑刚好可以实现
3. 前、中、后序遍历
前、中、后序遍历唯一的区别就是访问节点的时机不同
每个节点可以看成是有三次被经过:到达初遇,从左边回来再遇,遍历完右子树再遇,
这三次相遇恰好就对应前、中、后序的访问时机,
只需在迭代逻辑中找到这三次相遇的对应部分进行访问,即可完成前、中、后序遍历。
3.1 前序遍历
访问时机:第一次碰到,也就是左侧遍历要入栈的时候

此时访问,进行入栈即可。
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;//存储访问出元素
stack<TreeNode*> st;//栈——临时储存节点
TreeNode* cur = root;//用于游历整棵树的指针
while (!st.empty() || cur)
{
//遍历当前树的所有最左侧节点
while (cur)
{
v.push_back(cur->val);
st.push(cur);
cur = cur->left;
}
//取出栈顶节点
TreeNode* tmp = st.top();
st.pop();
//前序遍历右树
cur = tmp->right;//更新root为栈顶节点的右树
}
return v;
}
3.2 中序遍历
访问时机:左侧节点访问已完成,节点出栈,马上要进入右树进行访问的时候
此时访问,进行入栈即可。
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* tmp = st.top();
st.pop();
v.push_back(cur->val);
//前序遍历右树
cur = tmp->right;//更新root为栈顶节点的右树
}
return v;
}
3.3 后序遍历
在整棵右树访问完成,再次回到这个节点的时候进行访问
由于访问右树是一个多层的迭代遍历,无法在这个单次的代码上直接找到访问的位置
观察后,右子树进行后序遍历的最后一个访问的节点是右树的根节点,访问完这个节点的下一个节点就是当前要访问的节点

所以每次访问完一个节点,都将这个节点进行记录,节点要出栈都先判断栈顶节点对应的右节点是否为已记录节点
- 若是,则出栈并进行访问,同时更新用于记录的节点,此时右树无需访问,直接访问下一个栈顶元素
- 否则说明当前是②的位置,先不出栈,先访问右树,右树回来再出栈
**特殊情况:**当右树为空,这个节点也要访问

如访问B的右树完时候,prev
是D,但此时B也得进行访问,所以右树为空也要加入出栈访问的判断条件
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> v;//存储访问出元素
stack<TreeNode*> st;//栈——临时储存节点
TreeNode* cur = root;//用于游历整棵树的指针
TreeNode* prev = nullptr;
while (!st.empty() || cur)
{
//遍历当前树的所有最左侧节点
while (cur)
{
st.push(cur);
cur = cur->left;
}
TreeNode* tmp = st.top();
if (tmp->right == prev || tmp->right == nullptr)
{
st.pop();
v.push_back(tmp->val);
prev = tmp;
cur = nullptr;//下一次循环直接当空树访问下一个栈中节点
}
else
{
cur = tmp->right;//更新root为栈顶节点的右树
}
}
return v;
}
边栏推荐
- 统计UTF-8字符串中的字符函数
- leetcode 665. Non-decreasing Array 非递减数列(中等)
- [Code Hoof Set Novice Village 600 Questions] Leading to the combination of formulas and programs
- useragent online lookup
- Transfer Learning - Domain Adaptation
- focus on!Haitai Fangyuan joins the "Personal Information Protection Self-discipline Convention"
- 高效并发:Synchornized的锁优化详解
- MATLAB program design and application 2.4 Common internal functions of MATLAB
- Given an ip address, how does the subnet mask calculate the network number (how to get the ip address and subnet mask)
- Student management system on the first day: complete login PyQt5 + MySQL5.8 exit the operation logic
猜你喜欢
关注!海泰方圆加入《个人信息保护自律公约》
【论文精读】iNeRF
Structure of the actual combat battalion module eight operations
Audio alignment using cross-correlation
统计UTF-8字符串中的字符函数
PCB叠层设计
iNeuOS industrial Internet operating system, equipment operation and maintenance business and "low-code" form development tools
OSPFv3的基本配置
Bika LIMS open source LIMS set - use of SENAITE (detection process)
[NLP] What is the memory of the model!
随机推荐
20. Support vector machine - knowledge of mathematical principles
统计UTF-8字符串中的字符函数
JS basic exercises
Bika LIMS open source LIMS set - use of SENAITE (detection process)
登录业务实现(单点登录+微信扫码+短信服务)
ECCV 2022 Huake & ETH propose OSFormer, the first one-stage Transformer framework for camouflaging instance segmentation!The code is open source!...
[Code Hoof Set Novice Village 600 Questions] Leading to the combination of formulas and programs
Architecture Battalion Module 8 Homework
【AcWing】The 62nd Weekly Match 【2022.07.30】
Niuke.com brush questions (1)
Chapter VII
求n以内的素数
server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none failed
AI 自动写代码插件 Copilot(副驾驶员)
全网一触即发,自媒体人的内容分发全能助手——融媒宝
leetcode: 6135. The longest ring in the graph [inward base ring tree + longest ring board + timestamp]
GateWay implements load balancing
Go mode tidy reports an error go warning “all” matched no packages
UVM RAL model and built-in seq
Given an ip address, how does the subnet mask calculate the network number (how to get the ip address and subnet mask)