当前位置:网站首页>Binary tree non-recursive traversal
Binary tree non-recursive traversal
2022-07-31 22:11:00 【Massachusetts_11】
1. 遍历一棵树

前、中、The path of the post-order traversal is actually the same,They all travel the same way.
前、中、The results of post-order access are different,In fact, the timing of accessing the nodes is different:
前序:Visit a node as soon as you encounter it
中序:After visiting the left tree, go to visit
后序:After visiting the right subtree, visit again
如下是B节点的前、中、Post-order access timing
2. 非递归遍历
2.1 理解
The previous recursive traversal,Think of a tree as a symmetrical structure:左子树根右子树,With the help of recursive functions,You can enter the left and right subtrees for access;
But if you want to do it within the current function迭代访问,The previous left-right subproblem approach is difficult to implement.
Here we might as well take a look at the path graph of this traversal:

Walk down the far left firstA-B-D
然后向上,走D的右子树、B的右子树、A的右子树,走完AThe return of the right subtree means the traversal is over
Here access to the right subtree can be regarded as one子问题——Visit another tree rooted at the right node,Go back to the beginning;
It can be found that the order in which the nodes on the left go for the first time is from top to bottom:A-B-D,The order in which the right subtree is visited at the next encounter is againD-B-A,恰好相反,因此可以用栈的结构,When walking from the left, first save the nodes from top to bottom,When traversing to the end,When it is empty, remove the node at the top of the stack,Use this node to access its right tree;
At the same time by virtue of the stack structure,When entering the right tree,Go to the node of the right tree,Still into this stack,When the right tree is finished walking back,All the pushed nodes of the right tree have also been taken out,Again, only the nodes on the previous trunk are left,Mainline logic can also continue,Similar to the logic of the recursive way——No matter how complicated the logic of recursion is,Complete the branch task and come back,My main quest is still going on as normal.
2.2 实现
注:The following only provides methods for traversing the entire tree non-recursively,前、中、The timing of subsequent access to the node is not written,具体见后.
变量定义:

实现:
Traverse the leftmost node,At the same time, they are pushed onto the stack in turn

Start fetching elements from the stack

Access its right tree through this node

The judgment of the end of the traversal
- The elements in the stack are fetched——栈空
- At the same time, the current root node corresponds to an empty tree

The case where the subtree is empty(Back to the main question):
Skip the traversal of the current tree,Take the next node from the stack
The current logic just works

3. 前、中、后序遍历
前、中、The only difference between post-order traversal is the timing of visiting nodes
Each node can be seen as being traversed three times:first encounter,Come back from the left and meet again,Meet again after traversing the right subtree,
These three encounters happened to correspond to the previous ones、中、subsequent access timing,
Just find the corresponding parts of these three encounters in the iterative logic to visit,before you can finish、中、后序遍历.

3.1 前序遍历
访问时机:第一次碰到,That is, when the left traversal is to be pushed into the stack

此时访问,You can put it on the stack.
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;//Storage accesses out elements
stack<TreeNode*> st;//栈——Temporary storage node
TreeNode* cur = root;//A pointer for traversing the entire tree
while (!st.empty() || cur)
{
//Traverse all leftmost nodes of the current tree
while (cur)
{
v.push_back(cur->val);
st.push(cur);
cur = cur->left;
}
//取出栈顶节点
TreeNode* tmp = st.top();
st.pop();
//前序遍历右树
cur = tmp->right;//更新rootis the right tree of the top node of the stack
}
return v;
}
3.2 中序遍历
访问时机:Left node access is complete,节点出栈,It's about time to enter the right tree for access

此时访问,You can put it on the stack.
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> v;//Storage accesses out elements
stack<TreeNode*> st;//栈——Temporary storage node
TreeNode* cur = root;//A pointer for traversing the entire tree
while (!st.empty() || cur)
{
//Traverse all leftmost nodes of the current tree
while (cur)
{
st.push(cur);
cur = cur->left;
}
//取出栈顶节点
TreeNode* tmp = st.top();
st.pop();
v.push_back(cur->val);
//前序遍历右树
cur = tmp->right;//更新rootis the right tree of the top node of the stack
}
return v;
}
3.3 后序遍历
Access is done on the entire right tree,Visit when you come back to this node again
Since accessing the right tree is an iterative traversal of multiple layers,The location of the visit cannot be found directly on this single code
观察后,The last node visited in the postorder traversal of the right subtree is the root node of the right tree,The next node after visiting this node is the node to be visited currently

So visit one node at a time,This node is recorded,Before a node is popped from the stack, it must first determine whether the right node corresponding to the top node of the stack is a recorded node
- 若是,则出栈并进行访问,同时Update the node for logging,The right tree does not need to be visited at this time,Direct access to the next top element of the stack
- Otherwise, it indicates that it is currently②的位置,先不出栈,先访问右树,The right tree comes back and pops the stack again
**特殊情况:**When the right tree is empty,This node is also visited

如访问BWhen the right tree is finished,prev是D,但此时Balso have to visit,Therefore, if the right tree is empty, the judgment condition for pop-up access should also be added

vector<int> postorderTraversal(TreeNode* root)
{
vector<int> v;//Storage accesses out elements
stack<TreeNode*> st;//栈——Temporary storage node
TreeNode* cur = root;//A pointer for traversing the entire tree
TreeNode* prev = nullptr;
while (!st.empty() || cur)
{
//Traverse all leftmost nodes of the current tree
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;//The next loop directly accesses the next node in the stack as the empty tree
}
else
{
cur = tmp->right;//更新rootis the right tree of the top node of the stack
}
}
return v;
}
边栏推荐
- Architecture Battalion Module 8 Homework
- Verilog implements a divide-by-9 with a duty cycle of 5/18
- spark reports an error OutOfMemory "recommended collection"
- C language parsing json string (json object is converted to string)
- useragent online lookup
- Flink_CDC construction and simple use
- 顺序表的实现
- Thymeleaf是什么?该如何使用。
- A few permanent free network transmission, convenient and simple (Intranet through tutorials)
- What's wrong with the sql syntax in my sql
猜你喜欢

Implementing a Simple Framework for Managing Object Information Using Reflection
![[Code Hoof Set Novice Village 600 Questions] Merge two numbers without passing a character array](/img/4d/038e6cd6ecad19934122cff89f4d76.png)
[Code Hoof Set Novice Village 600 Questions] Merge two numbers without passing a character array

Flink_CDC construction and simple use

Student management system on the first day: complete login PyQt5 + MySQL5.8 exit the operation logic

Basic configuration of OSPFv3

【公开课预告】:超分辨率技术在视频画质增强领域的研究与应用

MATLAB program design and application 2.4 Common internal functions of MATLAB

useragent online lookup

Memblaze released the first enterprise-grade SSD based on long-lasting particles. What is the new value behind it?

Redis Overview: Talk to the interviewer all night long about Redis caching, persistence, elimination mechanism, sentinel, and the underlying principles of clusters!...
随机推荐
flowable workflow all business concepts
21. Support Vector Machine - Introduction to Kernel Functions
Carbon教程之 基本语法入门大全 (教程)
Several methods for deleting specified elements in Golang slices
Federated Learning: Multi-source Knowledge Graph Embedding in Federated Scenarios
Realize serial port receiving data based on STM32 ring queue
高通cDSP简单编程例子(实现查询高通cDSP使用率、签名),RK3588 npu使用率查询
Bionic caterpillar robot source code
SiC MOSFET的短路特性及保护
A solution to the server encountered an internal error that prevented it from fulfilling this request [easy to understand]
PCB stackup design
Thymeleaf是什么?该如何使用。
Linux环境redis集群搭建「建议收藏」
架构实战营模块 8 作业
PCB叠层设计
二叉树非递归遍历
求n以内的素数
Go mode tidy reports an error go warning “all” matched no packages
Socket回顾与I/0模型
-xms -xmx(information value)