【问题标题】:Why do we need to detect a loop in a linked list为什么我们需要检测链表中的循环
【发布时间】:2023-04-02 08:29:01
【问题描述】:

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

【问题讨论】:

  • “链表”和“循环”在定义上是矛盾的。你确定这些问题不是关于一般图中的循环吗?
  • @Henry 这是一个相当常见的面试问题。 OP 可能要求实际工作中可能适用的场景。

标签: algorithm data-structures linked-list cyclic-reference


【解决方案1】:

在现实生活中,您可能永远不需要检测链表中的循环,但执行此操作的算法很重要,我在现实生活中使用过很多次。

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

循环查找算法在 Pollard 的“rho”分解算法中也很有用 (https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm)

您在学习这些算法时学到的想法也将在以后学习其他更复杂的事物时有用。

预计到达时间:

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

【讨论】:

  • 还有一件事,可能这对你来说很琐碎,当我们创建一个列表时,我们总是不断地添加新元素,那么链表是如何形成循环的。还是开发人员错误地编写了一些创建循环的错误逻辑
  • 在开始迭代之前,我们还必须检查链表中的循环。
  • 您不必在开始迭代之前检查循环,因为可以将循环检测与处理结合起来 - 以最小的开销(只需再保留一个指针并更新它)。如果您不处理整个列表(例如,您正在寻找链表中的一个元素并且它出现在列表的早期),那么首先检查循环将是低效的。但是,如果您在处理时更改元素,则必须更详细地考虑它。
  • @NikhilBansal 当通过添加元素创建链表时,它以循环结束的可能性不大。这就是为什么您可能永远不需要检查链表中的循环的原因之一 :)。树通常是通过创建引用其他节点的节点来制作的,这样比较危险。
【解决方案2】:

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

你可以在这里找到答案

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

【讨论】:

    【解决方案3】:

    因为,如果您有这样的列表(例如):

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

    以及遍历它的代码如下:

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

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

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

    请注意,某些循环链表确实有效。我见过的一个例子是一个用于调度头部和尾部无关的进程列表(因为处理它们的东西希望永远循环它们)。因此调度程序将类似于:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 2013-07-14
      相关资源
      最近更新 更多