编程语言
首页 > 编程语言> > JAVA怎么判断链表成环

JAVA怎么判断链表成环

作者:互联网

JAVA怎么判断链表成环:
如果保证两个步距不同的游标同时对链表遍历,那么只要它们相遇了就证明链表有环
为了方便理解,我们可以先想象成 慢的人速度为1、快的人速度为2。
开始写代码:

Node p1 = head;//先都指向头结点
Node p2 = head;
int times = 0;//相遇0次
while(p2!=null&&p2.next!=null)//如果快游标到结尾就退出循环
{
	p1=p1.next;//一次走一步
	p2=p2.next.next;//一次走两步
	if(p1==p2)
	{
		return isCycle;//相遇即证明有环
	}
}

疑点解释

有没有可能在循环内慢速的游标会始终和快速游标无法相遇

如果你没有这个疑惑,就不用看了,如果你有,那么我跟你讲下为什么:
你的逻辑应该是这么想的:高速游标一直循环,低速游标也一直循环,有可能导致慢游标始终无法相遇于在整点位置。
先放结论:不可能
公式推导(感谢评论区小伙伴)
前提:快慢游标进入循环后一定会先后落脚于同一个交点。
如下图所示,我们设圆为链表的循环部分,设其有8个循环结点。其中快游标的步距为2(速度为2),慢游标步距为1(速度为1)。故快游标的遍历路线为顺时针的绿色虚线,慢游标的遍历路线为顺时针橙色虚线。
不难看出快慢游标都会先后驻足于绿色点。
循环链表
为了增加说服力,我们将慢游标步距设为2,快游标步距设为3, 还是存在不同时间的公共驻足点:
循环链表2
所以假设快慢游标先后落脚于循环结点x,如下图,此时快游标先抵达x,此时慢游标一定在它之前的某个结点:

快游标抵达
然后慢游标抵达x结点,此时快游标可以在循环结点中的任何位置。
慢游标抵达
都进入循环链表后,我们希望会出现一下场景:快慢游标同时相遇于x结点。
相遇
假设
快慢游标相遇于曾先后驻足的x结点。
已知
慢游标步距分别为xA、xB;
链表中循环部分长度为s;
慢游标从进入循环结点x到两个游标相遇的时间为t;
推理
(xA-xB)* t则为快游标在循环中比慢游标多走的距离。
只要满足:[(xA-xB)* t]%s=0即可证明它们会在循环中相遇于结点x。
故只要存在一个正整数t使得(xA-xB)*t = ns成立即可证明我们的假设。
因为xA!=xB,可得 t=ns/(xA-xB)不难看出(xA-xB)必为正整数,n为任意正整数,故一定存在一个正整数t使得等式成立。
结论:
综上所述,可得出,当快慢游标步距不相同的情况下,不论链表中循环结点的个数有多少,必定存在一个时刻t使得两个游标会在同一结点x相遇。

标签:步距,结点,JAVA,xA,游标,链表,循环,成环
来源: https://blog.csdn.net/weixin_44159662/article/details/106118305