使用兩個指針pfast, pslow從頭節點開始,依次向後走,pfast一次兩步,pslow一次一步,當兩個指針相等,則存在環,否則不存在。
當pfast與pslow相遇的時候,pfast經過的環形路程比pslow經過的環形路程一定多了環長的整數倍。從起點走到連接點與pfast和pslow相遇的點繼續走到連接點的距離相等。
假設從起點到連接點走a步到連接點,記爲S(a),設pslow走x步與pfast相遇,則有S(2x) = 2S(x),即2 x = x + n b;b爲環的長度,可得x = nb
則S(x +a) = S(a+nb)因此,從起點和相遇點一次一步會相遇在連接點。
找到連接點,則環的長度及鏈表總長度都迎刃而解。
typedef struct node{
struct node *next;
}Node, *Pnode;
Pnode find_circle(Pnode head)
{
Pnode pfast,pslow;
if(head == NULL)
return NULL;
pfast = head;
pslow = head;
while(pfast && pfast->next){
pfast = pfast->next->next;
pslow = pslow->next;
if(pfast == pslow) //兩個指針相遇
return pfast;
}
return NULL;
}
Pnode find_entrance(Pnode head, Pnode pmeet)
{
if(head == NULL || pmeet == NULL)
return NULL;
while(head){
if(head == pmeet) //相遇爲連接點,即入口點
return pmeet;
head = head->next;
pmeet = pmeet->next;
}
return NULL;
}