首页 > 代码库 > 如果单链表有环,求环的起始位置

如果单链表有环,求环的起始位置

问题:如果单链表中存在环,求环的起始位置

解:在上篇文章中,利用追逐法判断一个单链表是否存在环。求环的起始位置,需要求解单链表的长度和环的长度的关系。如果确定了单链表的长度和环的长度的关系,那么环的起始位置就呼之欲出了。

在判断单链表中有两个指针P和q,p每次前进两步,q每次前进一步,p的速度是q的两倍。设单链表的长度为L,环的长度为R,链表起点到环起点的距离为X,当p和q相遇时,慢指针总共走了S步,在环内总共走了a步,快指针总共走了2S步,此时满足:2S=S+n*R,所以S=n*R。

S=X+a;

X+a=(n-1)*R+R=(n-1)*R+L-X

X=(n-1)*R+L-X-a

其中(n-1)*R+L-X表示相遇的位置,L-X表示环的长度,L-X-a表示相遇点到达环起始位置的距离。也就是说,链表起点到环起点的距离X等于从相遇位置到达环起点的距离。这一结论是解决这道题的理论基础。当快慢指针相遇后,让快指针p重新指向链表的起点位置,重新设置p的速度和q的速度相同,当p和q再次相遇时的位置就是环的起始位置。具体实现代码如下:

 1 linkNode *circleStart(linkNode *head)
 2 
 3 {
 4 linkNode *p,*q;
 5 p=q=head;
 6 while(p!=null && p->next!=null)
 7 {
 8 p=p->next->next;
 9 q=q->next;
10 if(p==q)
11 break;
12 }
13 if(p==q &&p!=null)
14 {
15 p=head;
16 while(p!=q)
17 {
18 p=p->next;
19 q=q->next;
20 }
21 return p;
22 }
23 else{
24 return null;
25 }
26 }

 

如果单链表有环,求环的起始位置