判断链表中是否存在环,可以使用如下定义进行判断:
定理:碰撞点p到连接点的距离=头指针到连接点的距离。
完整的程序如下:
/*********************************************************************
* 函数名称:linklist *IsLoop(linklist *head)
* 函数功能:判断链表是否含有环,并找出环的入口
* 参 数:head----链表的头结点
* 返 回 值:若有环,则返回链表中环的入口结点;否则返回NULL
* 说 明:程序参考定理:碰撞点p到连接点的距离=头指针到连接点的距离
*********************************************************************/
extern linklist *IsLoop(linklist *head)
{
linklist *p1=head, *p2=head;
int IsLoopFlag=0;
if(head==NULL)
return NULL;
while(p2->next!=NULL && p2->next->next!=NULL)
{
p1 = p1->next;
p2 = p2->next->next;
if(p1==p2)
{
IsLoopFlag = 1;
break;
}
}
if(!IsLoopFlag)
return NULL;
else
{
// p2指向头结点,p1在第一次相遇点。
// 之后利用定理,当p1再次等于p2时,相遇点即为环的入口结点
p2 = head;
while(p1!=p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
}
// 节点定义
/*********定义一个链表结点*********/
typedef struct node
{
int data; // 结点的数据域
struct node *next; // 结点的指针域
}linklist;