記憶口訣:循環當前,左右到底,右子有無,當前左右,後前前中
後左尾頭,右子反轉,next開頭,首尾相接,遍歷反轉
0)前中後代碼框架
TreeNode *cur=rootr,*temp=nullptr;
while(cur){
temp=cur->left;
if(temp){
while(temp->right&&temp->right!=cur)
temp=temp->right;
if(temp->right){
temp->right=nullptr;
//後序節點處理
}
else{
temp->right=cur;
//前序節點處理
cur=cur->left;
continue;
}
}
else
//前序節點處理
//中序節點處理
cur=cur->right;
}
1)中序
void InOrder(TreeNode* root){//morris中序(左,根,右)
TreeNode *cur=root,*pre=nullptr,*temp=nullptr;
while(cur){
temp=cur->left;
if(temp){
while(temp->right&&temp->right!=cur)
temp=temp->right;
if(temp->right)
temp->right=nullptr;
else{
temp->right=cur;
cur=cur->left;
continue;
}
}
operate(cur),pre=cur;//如果需要用到前驅節點則需定義pre,否則不用
cur=cur->right;
}
}
2)前序
void PreOrder(TreeNode* root){//morris前序(根,左,右)
TreeNode *cur=root,*pre=nullptr,*temp=nullptr;
while(cur){
temp=cur->left;
if(temp){
while(temp->right&&temp->right!=cur)
temp=temp->right;
if(temp->right)
temp->right=nullptr;
else{
temp->right=cur;
operate(cur),pre=cur;//如果需要用到前驅節點則需定義pre,否則不用
cur=cur->left;
continue;
}
}
else
operate(cur),pre=cur;//如果需要用到前驅節點則需定義pre,否則不用
cur=cur->right;
}
}
3)後序
void PostOrder(TreeNode* root){//morris前序(左,右, 根)
TreeNode *cur=root,*pre=nullptr,*temp=nullptr;
while(cur){
temp=cur->left;
if(temp){
while(temp->right&&temp->right!=cur)
temp=temp->right;
if(temp->right){
temp->right=nullptr;
PostHelper(cur->left);
}
else{
temp->right=cur;
cur=cur->left;
continue;
}
}
cur=cur->right;
}
operate(head)
}
void PostHelper(TreeNode* root){
//1 鏈表(右)逆序,頭節點爲root
TreeNode *cur=root,*pre=nullptr,*next=nullptr;
while(cur){//next開頭,首位相接,方便記憶,如下
next=cur->right;//next=cur->right=pre=cur=next
cur->right=pre;
pre=cur;
cur=next;
}
//2 右邊界逆序遍歷
cur=pre;//此時頭節點爲pre
while(cur){
operate(cur);
cur=cur->right;
}
//3 鏈表(右)逆序,頭節點爲pre
cur=pre,pre=nullptr,next=nullptr;
while(cur){
next=cur->right;
cur->right=pre;
pre=cur;
cur=next;
}
}