证明链表的最快方式是循环?在python中

时间:2013-12-03 14:28:23

标签: python algorithm data-structures linked-list

有人可以告诉我证明链表包含循环的最佳方法吗? 我正在使用一个带有两个指针的算法,一个步骤缓慢移动一步,另一个步骤移动得更快。

class Node(object):
    def __init__(self, value, next=None):
        self.next=next
        self.value=value
def create_list():
    last = Node(8)
    head = Node(7, last)
    head = Node(6, head)
    head = Node(5, head)
    head = Node(4, head)
    head = Node(3, head)
    head = Node(2, head)
    head = Node(1, head)
    last.next = head
    return head

def is_circular(head):
    slow = head
    fast = head
    while True:
        slow = slow.next
        fast = fast.next.next
        print slow.value, fast.value
        if slow.value == fast.value:
            return True
        elif slow is fast:
            return False

if __name__ == "__main__":
    node = create_list()
    print is_circular(node)

4 个答案:

答案 0 :(得分:13)

一个好的算法如下,它可能是最好的。您不需要复制列表或任何内容,例如可以在恒定空间中完成

取两个指针并将它们设置到列表的开头。

让一次增加一个节点,一次增加另外两个节点。

如果列表中的任何一点都存在循环,则它们必须在某个点指向同一节点(不包括起始点)。显然,如果你到达列表的末尾,就没有循环。

修改
您的代码,但略有编辑:

def is_circular(head):

     slow = head
     fast = head

     while fast != None:
         slow = slow.next

         if fast.next != None:
              fast = fast.next.next
         else:
              return False

         if slow is fast:
              return True

    return False

答案 1 :(得分:2)

不知道最好的,但我能想到的最简单的是

>>> import json
>>> l = []
>>> l.append(l)
>>> json.dumps(l)
Traceback (most recent call last):
  ...
ValueError: Circular reference detected

答案 2 :(得分:1)

我会像其他任何语言一样测试它:

从头开始遍历列表,将所有访问过的元素添加到具有快速插入和查找的数据结构(例如集合)中。如果您在没有看到任何元素两次的情况下点击列表的末尾,则列表不是循环的。如果您看到两次元素,则列表为圆形。

如果两者都不成立,则列表无限。 : - )

答案 3 :(得分:0)

以下是这样做的方法:

  1. 从节点开始&将其指针存储在变量
  2. 开始访问下一个元素直到结束或重新访问起始节点。
  3. 如果达到结束,那么它不是圆形的其他圆形