Morris
}
//向右移动
cur=cur->right;
}没有左子树的点都只会遍历一次,有左子树的点都会遍历两次,但是增加的遍历次数是常数级的,并且没有重复的。所以总的来说总的复杂度仍是`O(N)`,空间为`O(1)`
### Morris先序遍历
对于能够到达两次的节点,在第一次遇见时进行打印,对于只能够到达一次的节点,则直接打印。
``` c++ "Morris"
void MorrisPreOrder(TreeNode* head){
if(head==nullptr){
return;
}
TreeNode* cur{head};
TreeNode* most_right{nullptr};
while(cur!=nullptr){
//来到左节点
most_right=cur->left;
if(most_right!=nullptr){
//进入到这个分支,就说明能来到该节点两次
//有左子树,则找到最右节点,记得一定是左子树,most_right->right!=cur是为了防止跳出左子树进入右子树
while(most_right->right!=nullptr && most_right->right!=cur){
most_right=most_right->right;
}
//第一次来到该节点
if(most_right->right == nullptr){
most_right->right=cur;
cur=cur->left;
cout<<cur->val<<endl;
//向左移动,直接进入下一次循环
continue;
}
else{
//第二次来到该节点,将most_right置空,然后向右移动
most_right->right=nullptr;
//cur=cur->right;
}
}
//执行到这,要么第二次来到,要么第一次来到,如果不加else分支,第二次来到cur时也会打印
//能进入这个分支,说明只能来到cur一次
else{
cout<<cur->val<<endl;
}
//向右移动
cur=cur->right;
}
}什么时候用递归套路什么时候用Morris?
Last updated