算法:定义p,q两个指针,p一次走一步,q一次走两步,如果q能一直走到尾说明没有环,如果前进过程中p与q相遇了则说明有环。
具体代码:
Node *IsLoop(List plist)//检测单链表是否有环
{
assert(plist!=NULL);
if(plist==NULL || plist->next==NULL)
{
return NULL;
}
Node *p=plist->next; //慢指针,一次走一步
Node *q=plist->next->next; //快指针,一次走两步
while(q!=NULL && q->next!=NULL)
{
if(q==p)
{
break;
}
p=p->next;
q=q->next->next;
}
if(q==NULL || q->next==NULL)
{
return NULL;
}
else
{
return p;
}
}
测试:
int main()
{
Node head;
InitList(&head); //初始化头节点
for(int i=0; i<=10; i++)
{
Insert_head(&head,i); //将0到10头插到单链表中
}
Show(&head);
Node *p = IsLoop(&head);
if(p == NULL)
{
printf("没有环\n");
}
else
{
printf("有环\n");
}
Node *q = Search(&head,3); //构造环
Node *s = Search(&head,0);
s->next = q;
p = IsLoop(&head);
if(p == NULL)
{
printf("没有环\n");
}
else
{
printf("有环\n");
}
return 0;
}
结果: