Morris Traversal的时间复杂度是O(n),空间复杂度O(1),利用了线索二叉树的思想。
使用Morris Traversal进行中序遍历的具体算法步骤总结如下:
1. 将根结点root设为当前结点cur。
2. 找到二叉树中以中序遍历时当前结点cur的前驱结点prev。如果当前结点没有前驱结点,便输出当前结点,并将当前结点的右孩子设置为当前结点;如果当前结点有前驱结点便进行3。(查找前驱的方法并不是进行一次中序遍历,当前结点的左孩子的右子树中最右的孩子便是当前结点的前驱)
3. 判断该前驱结点prev的右孩子是否已经设置为当前结点cur。如果prev的右孩子为NULL,则将prev的右孩子设为当前结点cur,并将当前当前结点的左孩子设为当前结点cur;如果prev的右孩子已经设置为cur了,那么我们将prev的右孩子设为空,并输出当前结点的值,再将当前结点的右孩子设置为当前结点。回到第二步。
4. 重复上面的2、3步骤直到当前结点为空。
算法图示如下:
中序遍历C++实现:
void inorderMorrisTraversal(TreeNode* root){
TreeNode * cur=root,* prev=NULL;
while(cur!=NULL){
if(cur->left==NULL){
printf("%d\n",cur->val);
cur=cur->right;
}
else{
prev=cur->left;
while(prev->right!=NULL&&prev->right!=cur)
prev=prev->right;
if(prev->right==NULL){
prev->right=cur;
cur=cur->left;
}
else{
prev->right=NULL;
printf("%d\n", cur->val);
cur=cur->right;
}
}
}
}