Morris遍历模板
作者:
rd0
,
2023-04-14 21:54:45
,
所有人可见
,
阅读 230
思想
- Morris遍历利用左右节点为空的空节点指针建立线索二叉树,将空闲的叶子节点指向上层的后继节点,保证右子树先于根被遍历到。实质是没有左子树的节点只会被访问一次,有左子树的节点会被访问两次,第一次访问建立向上走的线索,第二次访问清空之前建立的线索。
遍历过程
- 从根节点开始遍历,假设当前节点为cur:
- 如果cur没有左孩子,则前往cur的右孩子(即
cur = cur->right
)
- 如果cur有左孩子,则寻找左子树上的最右节点pre:
- 如果pre的右孩子为空,则将其右指针指向cur,cur向左移动;
- 如果pre的右孩子为cur,则将其右指针指向空,cur向右移动。
- 时间复杂度O(n),空间复杂度O(1)(不算保存答案用的数组)。
具体代码如下
#include <iostream>
#include <vector>
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) {}
};
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
TreeNode *pre, *cur;
cur = root;
while (cur) {
if (cur->left == nullptr) {
res.push_back(cur->val);
cur = cur->right;
} else {
pre = cur->left;
while (pre->right != nullptr && pre->right != cur) pre= pre->right;
if (pre->right == nullptr) {
res.push_back(cur->val);
pre->right = cur;
cur = cur->left;
} else {
pre->right = nullptr;
cur = cur->right;
}
}
}
return res;
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
TreeNode *pre, *cur;
cur = root;
while (cur != nullptr) {
if (cur->left == nullptr) {
res.push_back(cur->val);
cur = cur->right;
} else {
pre = cur->left;
while (pre->right != nullptr && pre->right != cur) pre= pre->right;
if (pre->right == nullptr) {
pre->right = cur;
cur = cur->left;
} else {
pre->right = nullptr;
res.push_back(cur->val);
cur = cur->right;
}
}
}
return res;
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
TreeNode *pre, *cur = root;
while (cur != nullptr) {
if (cur->right == nullptr) {
res.push_back(cur->val);
cur = cur->left;
} else {
pre = cur->right;
while (pre->left != nullptr && pre->left != cur) pre = pre->left;
if (pre->left == nullptr) {
res.push_back(cur->val);
pre->left = cur;
cur = cur->right;
} else {
pre->left = nullptr;
cur = cur->left;
}
}
}
reverse(res.begin(), res.end());
return res;
}