当前位置:网站首页>Morris traversal
Morris traversal
2022-06-24 23:32:00 【Today I will also write bugs】
The traditional traversal method is either recursive or stack , The space complexity of its traversal is O(N), and Morris Traversal can be done with O(1) Spatial complexity of , And its time complexity is the same as that of the traditional method O(N).
List of articles
Morris Traversal introduction
Morris Traversal uses a large number of free pointers in the original tree , To save space .
Morris The traversal rule is :
Suppose the current node cur, At the beginning of the cur Go to the position of the head node
- If cur There is no left child ,cur To the right (cur=cur->right)
- If cur There are left children , Find the rightmost node on the left subtree mostRight
1). If mostRight The right pointer of points to null , Make it point cur, then cur Move to the left (cur=cur->left)
2). If mostRight The right pointer of points to cur, Make it point nullptr, then cur To the right (cur=cur->right) - cur It's empty time , Stop traversal .
class Node
{
public:
Node(int _value)
{
value = _value;
left = nullptr;
right = nullptr;
}
int value;
Node* left;
Node* right;
};
void morris(Node* head)
{
if (head == nullptr)
{
return;
}
Node* cur = head;
//mostRight by cur The rightmost node of the left tree
Node* mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
// If cur No left tree , that cur Will move directly to the right
if (mostRight != nullptr)
{
// look for cur The rightmost node of the left tree , When empty or equal to cur Stop when
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
// If it is empty , Explain the first time to the rightmost node , Now point the pointer to cur
// then cur Move to left subtree
if (mostRight->right == nullptr)
{
mostRight->right = cur;
cur = cur->left;
continue;
}
// here mostRight->right == cur
// Indicates the second arrival at the node , Recover the pointer of this node
else
{
mostRight->right = nullptr;
}
}
cur = cur->right;
}
}
Morris The first sequence traversal
The order of preorder traversal is about the root , because Morris Traversal may reach a node twice , So we need to print the first time we reach the node .
void morrisPre(Node* head)
{
if (head == nullptr)
{
return;
}
Node* cur = head;
//mostRight by cur The rightmost node of the left tree
Node* mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
// If cur No left tree , that cur Will move directly to the right
if (mostRight != nullptr)
{
// look for cur The rightmost node of the left tree , When empty or equal to cur Stop when
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
// If it is empty , Explain the first time to the rightmost node , Now point the pointer to cur
// then cur Move to left subtree
if (mostRight->right == nullptr)
{
cout << cur->value << endl;
mostRight->right = cur;
cur = cur->left;
continue;
}
// here mostRight->right == cur
// explain mostRight Arrive at this node for the second time , Recover the pointer of this node
else
{
mostRight->right = nullptr;
}
}
//cur There is no left tree , Print directly cur, And then move cur To right subtree
else
{
cout << cur->value << endl;
}
cur = cur->right;
}
}
Morris In the sequence traversal
Middle order traversal follows the principle of left root right , For a node , Print on second arrival .
void morrisIn(Node* head)
{
if (head == nullptr)
{
return;
}
Node* cur = head;
//mostRight by cur The rightmost node of the left tree
Node* mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
// If cur No left tree , that cur Will move directly to the right
if (mostRight != nullptr)
{
// look for cur The rightmost node of the left tree , When empty or equal to cur Stop when
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
// If it is empty , Explain the first time to the rightmost node , Now point the pointer to cur
// then cur Move to left subtree
if (mostRight->right == nullptr)
{
mostRight->right = cur;
cur = cur->left;
continue;
}
// here mostRight->right == cur
// explain mostRight Arrive at this node for the second time , Recover the pointer of this node
else
{
mostRight->right = nullptr;
}
}
// Because the first time mostRight->right = cur;
// So the left subtree cur You can reach this node twice , Print the second time
cout << cur->value << endl;
cur = cur->right;
}
}
Morris After the sequence traversal
Postorder traversal is the order of left and right roots , Because we didn't set the parent pointer , Therefore, it is impossible to print from the right subtree to the root node . Unless the stack structure is used in reverse order , But this violates the space complexity of O(1) The purpose of .
therefore , We need to flip the linked list , Point the right pointer to its parent node , Change back after printing .
// Flip list
Node* reverseEdge(Node* from)
{
Node* pre = nullptr;
Node* next = nullptr;
while (from != nullptr)
{
next = from->right;
from->right = pre;
pre = from;
from = next;
}
return pre;
}
void printEdge(Node* head)
{
// Regard the rightmost part of the right subtree as a linked list
// Flip the linked list
Node* tail = reverseEdge(head);
Node* cur = tail;
while (cur != nullptr)
{
cout << cur->value << endl;
cur = cur->right;
}
// Turn the linked list back
reverseEdge(tail);
}
void morrisPos(Node* head)
{
if (head == nullptr)
{
return;
}
Node* cur = head;
//mostRight by cur The rightmost node of the left tree
Node* mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
// If cur No left tree , that cur Will move directly to the right
if (mostRight != nullptr)
{
// look for cur The rightmost node of the left tree , When empty or equal to cur Stop when
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
// If it is empty , Explain the first time to the rightmost node , Now point the pointer to cur
// then cur Move to left subtree
if (mostRight->right == nullptr)
{
mostRight->right = cur;
cur = cur->left;
continue;
}
// here mostRight->right == cur
// Indicates the second arrival at the node , Recover the pointer of this node
else
{
mostRight->right = nullptr;
// Print the right boundary of the left subtree of a tree in reverse order
printEdge(cur->left);
}
}
cur = cur->right;
}
// Print the right boundary of the whole tree in reverse order
printEdge(head);
}
边栏推荐
- [JS] - [linked list - application] - learning notes
- 7-2 后序+中序序列构造二叉树
- 中学校园IP网络广播系统解决方案-校园数字IP广播系统方案设计指南
- 7-3 最大子段和
- SimpleDateFormat 格式化和解析日期的具体类
- 7-7 digital triangle
- [JS] - [array, Stack, queue, Link List basis] - Notes
- R language uses GLM function to build Poisson log linear regression model, processes three-dimensional contingency table data to build saturation model, uses summary function to obtain model summary s
- jar中没有主清单属性
- Design and practice of vivo server monitoring architecture
猜你喜欢
宁德时代定增450亿:高瓴认购30亿 曾毓群仍控制23%股权
22map introduction and API
Helix distance of point
【js】-【树】-学习笔记
2021-2022 China's financial digitalization "new" insight Industry Research Report
[JS] - [linked list - application] - learning notes
js监听页面或元素scroll事件,滚动到底部或顶部
Fibonacci
[JS] - [stack, team - application] - learning notes
[JS] - [array application] - learning notes
随机推荐
都2022年了,你还不了解什么是性能测试?
Simple use of libnum Library (hexadecimal string conversion)
Pseudo original intelligent rewriting API Baidu - good collection
Hydropower project construction scheme based on 3D GIS Development
Why is it that the "Zhongtai" that was originally eaten by civil engineering is no longer fragrant?
379. hide and seek
[JS] - [string - application] - learning notes
[introduction to UVM== > episode_8] ~ sequence and sequencer, sequence hierarchy
R语言使用epiDisplay包的aggregate函数将数值变量基于因子变量拆分为不同的子集,计算每个子集的汇总统计信息、自定义FUN参数为多个统计量函数名称的列表计算多个统计量
数字IC设计经验整理(二)
No main manifest attribute in jar
Whereabouts computer desktop small arrow
点的螺旋距离
22map introduction and API
第六章 网络学习相关技巧5(超参数验证)
idea创建模块提示已存在
7-5 最大子矩阵和问题
Yyds dry goods inventory tells us 16 common usage scenarios of redis at one go
Collation of Digital IC design experience (II)
The R language uses the matchit package for propensity matching analysis and match The data function constructs the matched sample set, and performs Welch double sample t-test analysis and double inde