问题
Could someone please let me know the best way to prove a linked list contains a loop? I am using an algorithm with two pointer, one is moving slow with one steps and one is moving faster with two steps.
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)
回答1:
A good algorithm is as follows, it may very well be the best. You do not need to copy the list or anything, like that, it can be done in constant space.
Take two pointers and set them to the beginning of the list.
Let one increment one node at a time and the other two nodes at a time.
If there is a loop at any point in the list, they will have to be pointing to the same node at some point (not including the starting point). Obviously if you reach the end of the list, there is no loop.
EDIT:
Your code, but slightly edited:
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
回答2:
Don't know about best, but simpliest I can think of is
>>> import json
>>> l = []
>>> l.append(l)
>>> json.dumps(l)
Traceback (most recent call last):
...
ValueError: Circular reference detected
回答3:
I would test it just like in any other language:
Start traversing the list from the start, adding all visited elements into a data structure (e.g. a set) with fast insertion and lookup. If you hit the end of the list without seeing any element twice, the list is not circular. If you see an element twice, the list is circular.
If neither is true, the list is infinite. :-)
回答4:
Here is way to do it:
- Start from a node & store its pointer in variable
- Start visiting next elements till end or the start node is revisited.
- if end is reached then it is not circular else circular
来源:https://stackoverflow.com/questions/20353835/fastest-way-to-prove-linked-list-is-circular-in-python