Morris二叉树遍历:
来到当前的节点:Cur
- 如果Cur无左孩子,Cur向右移动 (Cur = Cur.right)
- 如果Cur有左孩子,找到Cur左子树上最右的节点,记为 mostright
- (1) 如果mostright的右指针为null,则让其右指针指向Cur,并使Cur向左移动 (Cur = Cur.left)
- (2) 如果mostright的右指针指向Cur,则让其右指针指向null,并使Cur向右移动 (Cur = Cur.right)
思路:(可模拟先序中序后序)
- 该节点有左子节点,则可以访问到该节点两次
- 该节点无左子节点,则只能访问到该节点一次
#include <iostream>
using namespace std;
class Node{
public:
int val;
Node *left, *right;
explicit Node(int x) :val(x), left(nullptr), right(nullptr) {}
};
void printEdge(Node*&);
void reverseEdge(Node *&);
Morris先序遍历:
void MorrisPre(Node* head)
{
if (head == nullptr)return;
Node *cur = head;
Node *mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
if (cur->left != nullptr)
{
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
if (mostRight->right == nullptr)
{
cout << "第一次:" << cur->val << endl;
mostRight->right = cur;
cur = cur->left;
continue;
}
else
{
mostRight->right = nullptr;
}
}
else
{
cout << "第二次:" << cur->val << endl;
}
cur = cur->right;
}
}
Morris中序遍历:
void MorrisIn(Node* head)
{
if (head == nullptr)return;
Node *cur = head;
Node *mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
if(cur->left != nullptr)
{
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
if(mostRight->right == nullptr)
{
mostRight->right = cur;
cur = cur->left;
continue;
}else
{
mostRight->right = nullptr;
}
}else
{
}
cout << "第二次:" << cur->val << endl;
cur = cur->right;
}
}
Morris后序遍历:
void MorrisPos(Node* head)
{
if (head == nullptr)return;
Node *cur = head;
Node *mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
if (cur->left != nullptr)
{
while (mostRight->right != nullptr && mostRight->right != cur)
{
mostRight = mostRight->right;
}
if (mostRight->right == nullptr)
{
mostRight->right = cur;
cur = cur->left;
continue;
}
else
{
mostRight->right = nullptr;
printEdge(cur->left);
}
}
else
{
}
cur = cur->right;
}
printEdge(head);
}
void printEdge(Node *& node)
{
reverseEdge(node);
Node *lastNode = nullptr;
Node *nextNode = node->right;
while (nextNode != nullptr)
{
cout << node->val << endl;
node->right = lastNode;
lastNode = node;
node = nextNode;
nextNode = nextNode->right;
}
cout << node->val << endl;
node->right = lastNode;
}
void reverseEdge(Node *&node)
{
Node *lastNode = nullptr;
Node *nextNode = node->right;
while (nextNode != nullptr)
{
node->right = lastNode;
lastNode = node;
node = nextNode;
nextNode = nextNode->right;
}
node->right = lastNode;
}