快慢指針的妙用
- 2022 年 1 月 31 日
- 筆記
1.判斷是否有環
通常情況下單鏈表的尾節點是為NULL的,如果一個單鏈表存在環必然會使尾節點的指針域
存放的是其中某個節點的地址,這樣就形成了環狀結構.
在環中fast走兩步,slow走一步,總會在某個時候,fast=slow
bool hasCycle(SLinkNode *L){ SLinkNode *p,*q; p=q=L; //如果鏈表中只存在一個節點或者為空鏈表,則沒有環 if(L==NULL||L->next==NULL) return false; while(q!=NULL&&q->next!=NULL){ q=q->next->next; p=p->next; if(p==q)//快慢指針相遇則存在環 return true; } return false; }
2.找到環的入口
在確定鏈表存在環後,可以通過一下演算法找到其入口
SLinkNode *findLoopStart(SLinkNode *L) { if(L==NULL&&L->next==NULL) return NULL; SLinkNode *slow,*fast; fast=slow=L; while(fast!=NULL&&fast->next!=NULL) { slow=slow->next; fast=fast->next->next; if(slow==fast) break; } SLinkNode *slow=L;//此時fast在相遇點,只需要將慢指針放回到起始點即可 while(slow!=fast) { slow=slow->next; fast=fast->next; } return slow; }
3:尋找中心節點
可以設置兩個指針fast和slow,讓fast先走兩步slow走一步,當fast到達尾節點時
slow剛好到達中心節點,如圖
SLinkNode *find_mid(SLinkNode *&L) { SLinkNode *p,*q,*s,*r; p=q=L; while(q!=NULL&&q->next!=NULL) { p=p->next;//p走一步 q=q->next->next;//q走兩步 } return p;
tips:
關於快慢指針還有幾種比較好的演算法,希望讀者根據以上三種演算法獨立進行探索!