判断一个单向链表是否有环,算法证明
判断一个单向链表是否有环:
给定链表的头指针:list *head。
步长法:
int looplist(list *head)


{
list *p ,*q;

if (head == NULL)
{
return 0;
}
p = head;
q = head;

while ((p->next != NULL) && (q->next != NULL) &&(q->next->next != NULL))
{
p = p->next;
q = q->next->next;

if (p == q)
{
return 1;
}
}
return 0;
}
证明步长法的正确性:
给定链表的头指针:list *head。
步长法:
int looplist(list *head)

{
list *p ,*q;
if (head == NULL)
{
return 0;
}
p = head;
q = head;
while ((p->next != NULL) && (q->next != NULL) &&(q->next->next != NULL))
{
p = p->next;
q = q->next->next;
if (p == q)
{
return 1;
}
}
return 0;
}
证明步长法的正确性:
如果链表有环,不妨假设其环长度为M(>=2)。
p指针首次到达交点(N0)时,q指针已经进入环。
设p=0;q=q-p;
再进过i(i>=0)步后,p=(p+i)%m;q=(q+2*i)%m;
则必存在一个i使得(p+i)%m = (q+2*i)%m。(p,q 都为常数)。
延伸:
给你一个单向链表的头指针,可能最后不是NULL终止,而是循环链表。怎么找出这个链表循环部分的第一个节点。
解决思路:
加入一个数组记录p指针移动痕迹,第一次重复处即是第一个循环节点。
浙公网安备 33010602011771号