C中怎么判断链表中是否有环?

C中怎么判断链表中是否有环?,第1张

用两个指针来遍历这个单向链表,第一个指针p1,每次走一步;
第二个指针p2,每次走两步;
当p2 指针追上p1的时候,就表明链表当中有环路了。
A判断链表是否有环
设置两个指针p1和p2,初始值均指向链表头,p1每次向前走一步,而p2每次向前走两步。
如果链表有环,则p2先进入环里,而p1后进入环里,两个指针在环中必定相遇。
如果p1与p2没有相遇,p2遍历到链表的尾部,则表示链表没有环。

B链表有环,确定环的入口点
设置p1指针指向链表头,p2指向相遇点,每次两个指针都是只走一步,两个指针必定相遇,
则相遇第一点为环入口点。

C计算环长
在环的入口点设置一个指针和一个计数器,让这个指针在环里面走,每走一步,计数器就加1,
当这个指针回到环的入口点的时候,计数器的值就是环长。
例如:
int testLinkRing(Link head)
{
Link t1=head,t2=head;while( t1->next && t2->next)
{
t1 = t1->next;if (NULL == (t2 = t2->next->next))return 0; // 无环 if (t1 == t2)return 1;
}
return 0;
}

给定一个单链表,只给出头指针h:
1、如何判断是否存在环?
2、如何知道环的长度?
3、如何找出环的连接点在哪里?
4、带环链表的长度是多少?

解法:
1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。
2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的 *** 作数就是环的长度s。
3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。
该定理的证明可参考:>判断单向链表是否有环,可以采用快指针与慢指针的方式来解决。即定义一个快指针fast和一个慢指针slow,使得fast每次跳跃两
节点,slow每次跳跃一个节点。如果链表没有环的话,则slow与fast永远不会相遇(这里链表至少有两个节点);如果有环,则fast与slow
将会在环中相遇。判断出链表有环以后,则需要算出进入环的第一个节点。在fast与slow第一次相遇后,设置一个节点pNode从链表的头部开始遍历,
每次只遍历一个节点。这样,当fast与slow再次相遇时,pNode所处的位置便是环的首部。以下该问题的实现源码(C语言描述):
LNode GetLoopNode(LNode head)
{
//前置条件的判断
if (!head)
{
return NULL;
}
//定义一个快指针和一个慢指针
LNode fast = head;
LNode slow = head;
while (fast && (fast->next))
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
//如果有环,则返回环的第一个节点
slow = head;
while (1)
{
fast = fast->next;
slow = slow->next;
if (fast == slow)
{
break;
}
}
return slow;
}
}
return NULL;
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13373800.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-23
下一篇 2023-07-23

发表评论

登录后才能评论

评论列表(0条)

保存