用快慢两个指针来判断是否有环;
在开头和相交点,分别用指针一步步的移动,相交的地方就是环的入口
快慢两个指针,快的在环内走了N圈,而慢的没有走掉一圈;
反证法:如果慢的在环内走了 1 圈,则快的至少要走2圈,中间比相交,所以假设不成立;
开头到环入口:a
环入口到相交点为:x
链表总长度为:L
快的走了 2S 步,慢的走了 S 步; 环大小为 r
则:
S = nr
a + x = nr
a = nr - x = (n-1)r + L - a - x
在开头和相交点,分别用指针一步步的移动,相交的地方就是环的入口
快慢两个指针,快的在环内走了N圈,而慢的没有走掉一圈;
反证法:如果慢的在环内走了 1 圈,则快的至少要走2圈,中间比相交,所以假设不成立;
开头到环入口:a
环入口到相交点为:x
链表总长度为:L
快的走了 2S 步,慢的走了 S 步; 环大小为 r
则:
S = nr
a + x = nr
a = nr - x = (n-1)r + L - a - x
a = L - a - x (相交点到环入口的长度)
/* 1. Judge there is a cycle in a link or not;
* 2. Create a link, insert a new node at the end;
* Create()
* 3. Set a crosspoint a the link
* SetPoint()
* 4. Find out the crosspoint;
* FindLoopPoint()
*/
#include <stdio.h>
#include <stdlib.h>
struct link
{
int data;
struct link *next;
};
typedef struct link LinkNode;
typedef struct link *LinkList;
LinkList
Create()
{
int data;
LinkList pHead,pEnd;
LinkList tmp;
pHead = NULL;
pEnd = NULL;
scanf("%d",&data);
while(data != -1){
tmp = (LinkList)malloc(sizeof(LinkNode));
if(tmp == NULL)
exit(-1);
tmp->data = data;
if(pHead == NULL){
pHead = tmp;
tmp->next = NULL;
pEnd = tmp;
}
else{
pEnd->next = tmp;
tmp->next = NULL;
pEnd = tmp;
}
printf("Input next data of %d:",data);
scanf("%d",&data);
}
return pHead;
}
void SetPoint(LinkList L,int cp)
{
int count = 0;
LinkList tmp;
LinkList iter;
if(L==NULL)
return;
for(count=0,iter=L;iter->next !=NULL;iter=iter->next){
count++;
if(count == cp)
tmp = iter;
}
if(count <= cp)
printf("Error value, cannot generate a cycle!\n");
iter->next = tmp;
}
int FindLoopPoint(LinkList L)
{
LinkList slow,fast;
slow = fast = L;
if(L == NULL)
return -1;
while(fast->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
break;
}
if(fast->next == NULL)
return -1;
else
puts("yaa! There is a cycle!");
slow = L;
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
return slow->data;
}
int main()
{
LinkList L = NULL;
LinkList pHead;
int count;
L = Create();
for(pHead = L;pHead != NULL;pHead = pHead->next)
printf("%d\t",pHead->data);
putchar('\n');
SetPoint(L,5);
printf("The point data is:%d\n",FindLoopPoint(L));
}