为什么我们需要检测链表中的循环



我看到很多关于如何检测链表中循环的问题/A,但我想了解我们为什么要这样做,换句话说,检测链表中循环的实际用例是什么

在现实生活中,你可能永远不需要检测链表中的循环,但这样做的算法很重要,我在现实生活中已经多次使用它们。

例如,很多时候,当链接的数据结构应该是树形时,我会递归地处理它。 但是,如果它不是树形并且有一个循环,那会导致无限递归和堆栈溢出,所以我喜欢在它爆炸之前抓住它。 我通常使用Brent的周期查找算法,因为它很容易适应我的递归处理,并且开销极低。

周期查找算法在波拉德的"rho"分解算法中也很有用(https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm(

您在学习这些算法时学到的想法在以后学习其他更复杂的东西时也很有用。

伊塔:

我应该补充一点,错误地产生循环的常见情况是用户专门创建链接的情况。 例如,在Java中,一个类可以有一个超类,程序员编写class C extends A {},例如。extends关键字在类之间创建链接。 如果他也写class A extends C,那么他就创建了一个循环,编译器必须检测到这种情况。

循环的链表没有结束,链表包含两个指向某个节点的链接 循环访问链表将多次生成循环中的所有节点 带有循环的格式错误(具有未知循环(的链表会导致对列表的迭代失败,因为迭代永远不会到达列表的末尾。因此,希望在尝试迭代之前能够检测到链表是否具有循环

你可以在这里找到答案

https://blog.ostermiller.org/find-loop-singly-linked-list

因为,如果你有一个这样的列表(例如(:

head -> A -> B -> C -+
^       |
+-------+

以及遍历它的代码如下:

node = head
while node <> null:
processNode(node)
node = node.next

那么你将永远无法完成循环。它将愉快地处理A, B, C, B, C, B, C,...永恒(或直到宇宙的热寂,以先到者为准(。

一个普通的链表永远不会循环。为了检测这样的退化列表,你可以看看这个答案。

请注意,一些循环链表确实有效。我看到的一个例子是用于调度的进程列表,其中头部和尾部无关紧要(因为处理它们的东西想要永远循环它们(。因此,调度程序将是这样的:

curr = somePointInList()
while true:
runForABit(curr)
curr = curr.next

相关内容

  • 没有找到相关文章

最新更新