Morris遍历是基于新线索二叉树的遍历算法,可以优化空间复杂度为O(1)
具体步骤如下:
1. 初始化当前节点cur为根节点。
2. 如果cur没有左子节点,则输出cur节点的值,然后将cur指向其右子节点。
3. 如果cur有左子节点,则找到cur节点在中序遍历中的前驱节点pre(即cur左子树中最右的节点)。
4. 如果pre的右子节点为空,将其右子节点指向cur,然后将cur指向其左子节点。
5. 如果pre的右子节点为cur,将其右子节点置为空,输出cur节点的值,然后将cur指向其右子节点。
6. 重复步骤2-5,直到cur为空。
使用Morris遍历算法,可以以O(1)的空间复杂度完成二叉树的遍历,但会破坏二叉树的结构。在遍历完成后,可以还原二叉树的结构。
例如使用Morris中序遍历算法:
#include <stdio.h>
#include <stdlib.h>
// 二叉树的结点结构体
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
// Morris中序遍历算法
void morrisInorder(struct TreeNode* root) {
struct TreeNode *cur = root;
while (cur != NULL) {
if (cur->left == NULL) {
printf("%d ", cur->val);
cur = cur->right;
} else {
// 找到当前节点左子树的最右结点
struct TreeNode *pre = cur->left;
while (pre->right != NULL && pre->right != cur) {
pre = pre->right;
}
if (pre->right == NULL) {
// 将最右结点的右指针指向当前结点
pre->right = cur;
cur = cur->left;
} else {
// 恢复最右结点的右指针为NULL
pre->right = NULL;
printf("%d ", cur->val);
cur = cur->right;
}
}
}
}
// 创建一个二叉树
struct TreeNode* createTree(int val) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->val = val;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
int main() {
// 创建一个二叉树
struct TreeNode* root = createTree(1);
root->left = createTree(2);
root->right = createTree(3);
root->left->left = createTree(4);
root->left->right = createTree(5);
printf("Morris Inorder Traversal: ");
morrisInorder(root);
return 0;
}