检查链表循环度

时间:2008-12-30 10:28:17

标签: algorithm

我需要一个方法,它将一个链表作为参数,如果它是循环的,则返回true或false。

ex:循环链表表示存在指向任何前一节点的节点指针。 我忘了告诉一些限制,我不能使用任何数据结构或动态内存分配。 我只能使用局部变量,而且算法可以在n个步骤中完成,就像有人对我说的那样(我现在想用两个指针?)

4 个答案:

答案 0 :(得分:10)

我相信你正在寻找Floyd's Cycle-Finding Algorithm。有一个比here更好的解释。

C和Scheme中还有一些实现,文档覆盖here

答案 1 :(得分:1)

标准哈希计数适用:

function has_loop(list):
    foreach node in list:
        address = address_of(node.next);
        element = hashtable.get(address);
        if (element == NULL):
            hashtable.put(address)
        else:
            return true
    return false

编辑:根据接受的答案的第二个链接,这可行,但效率低,这意味着有更多更有效的解决方案。

答案 2 :(得分:0)

这是微不足道的。

previousnodes ← set()
previousnodes.add(firstnode)
currentnode ← firstnode.next
while (currentnode in previousnodes) || (currentnode != null):
  previousnodes.add(currentnode)
  currentnode ← currentnode.next
when (currentnode = 0) return false
return true

答案 3 :(得分:0)

我自己遇到了这个问题的优雅解决方案,并且忍不住在这里发布(虽然我猜原来的海报很可能已经毕业了)。从开始节点开始,只需开始反转列表。如果列表不是循环的,则该过程将以Null结束,如果列表确实是循环的,则该过程将在起始节点处结束。所以它是一个具有恒定额外空间的线性时间算法。只需再次反转列表即可返回原始列表。