检测链表中循环中的第一个节点

时间:2016-04-18 14:17:03

标签: algorithm data-structures linked-list

最近,我已经通过算法检测循环中的第一个节点,如下所述: -

注意:此声明摘自网站: -

http://javabypatel.blogspot.in/2015/12/detect-loop-in-linked-list.html

现在重点是,我们将如何了解循环的起始节点。
步骤1:找到循环后,两个指针都指向处于会合点的公共节点                 内循环,
第2步:现在,将它们中的一个指针(比如乌龟)移到列表的头部,保持野兔                 指针在循环内的会合点处的相同位置。
第3步:开始一次移动两个指针。他们俩见面的地方就是开始                 循环/循环的节点。

让我们在下图中考虑案例2 : -

http://4.bp.blogspot.com/-79s5PBIexDE/Vmac8UlposI/AAAAAAAAAvQ/ejHRpGv_OLY/s1600/loop-in-linked-list-example.png

在应用所有步骤时,在案例2中,我被隐藏在第3步

"以下是针对案例2的Hare和Tortoise算法的解决方案。"

更快 - 1更慢 - 1
更快 - 5更慢 - 20
更快 - 22更慢 - 5
更快 - 20更慢 - 18
更快 - 18更慢 - 22
更快 - 1更慢 - 1 - 两个指针都在这里相遇..

因此,按照步骤2,我保持更快的指针,并将慢指针移动到1(这是列表的头部)。

因此,按照步骤3,我逐个递增每个指针。

因为它们都在" 1"中,将每个指针移动一个,将永远不会结束并且它会一直移动。

Q1。我是否知道,在STEP 3中我是否理解错误?

Q2。我可以假设,循环结束的节点是循环中的第一个节点吗?

1 个答案:

答案 0 :(得分:1)

您似乎已经正确地跟踪了给定的算法,直到最后一步。但是,在最后一步,我认为你误认为列表头这个词是指向列表第一个元素的指针。因此,您可能推断出循环永远不会结束,因为两个指针都会以相同的速度移动,而一个指针会先于另一个指针移动1.然而,我相信列表的头部被使用了引用列表中的第一个元素,而不是指向第一个元素的指针。

顺便说一句,我认为你的混淆不是因为你犯了一个错误,而是你在问题中提供的伪代码含糊不清。即使你没有误解列表的头部,你也会执行一次伪代码的第3步,并得出结论指针会在带有标签20的节点处相遇。(即列表中第一个节点之后的那个)因此,我认为步骤3可以使用以下一些说明。

第3步: 当野兔和乌龟处于不同的细胞时,一次将两个指针移动一个节点。

如此修正,如果遇到您提供的 case 2 这样的情况,将其中一个指针移动到列表的开头后,将无法满足迭代条件,因为指针已经见过面了。 (由于周期的开始位于列表的开头)

即使你原来的 Q2 还不太清楚,让我根据你对它的澄清回答它作为对我答案的评论。

enter image description here

在您提供的链接中,显示会议点M野兔和乌龟指针在您提供的伪代码的第1步之后符合与循环开始的确切距离为列表的第一个元素有。 (即上图中的距离p和r是相等的)因此,如果一个指针放在列表的开头而另一个指针保持在它们的会合点,那么如果两个指针都移动1,只要它们不在列表的同一个节点,是的,如果这样的循环存在,你可以假设他们遇到的地方将是列表中循环的开始。