Finding loop in a singly linked-list

前端 未结 13 1789
梦谈多话
梦谈多话 2020-11-28 18:41

How can I detect that whether a singly linked-list has loop or not?? If it has loop then how to find the point of origination of the loop i.e. the node from which the loop

13条回答
  •  猫巷女王i
    2020-11-28 18:55

    For the most part all the previous answers are correct but here is a simplified version of the logic with visual & code (for Python 3.7)

    The logic is very simple as others explained it. I'm gonna create Tortoise/slow and Hare/fast. If we move two pointers with different speed then eventually fast will meet the slow !! you can also think of this as two runners in a tack circular field. If the fast runner keeps going in circle then it will meet/pass the slow runner.

    So, we will move Tortoise/slow pointer with speed 1 for each iteration while we keep incrementing or move the Hare/fast pointer with speed of 2. Once they meet we know there is a cycle. This is also known as Floyd's cycle-finding algorithm

    Here is the Python code that does this (notice has_cycle method is the main part):

    #!/usr/bin/env python3
    class Node:
        def __init__(self, data = None):
            self.data = data
            self.next = None
        def strnode (self):
            print(self.data)
    
    
    class LinkedList:
        def __init__(self):
            self.numnodes = 0
            self.head = None
    
    
        def insertLast(self, data):
            newnode = Node(data)
            newnode.next = None
            if self.head == None:
                self.head = newnode
                return
    
            lnode = self.head
            while lnode.next != None :
                lnode = lnode.next
            lnode.next = newnode # new node is now the last node
            self.numnodes += 1
    
        def has_cycle(self):    
            slow, fast = self.head ,self.head  
            while fast != None:       
                if fast.next != None:
                     fast = fast.next.next
                else:
                     return False
                slow = slow.next  
                if slow == fast:
                    print("--slow",slow.data, "fast",fast.data) 
                    return True    
            return False
    
    
    linkedList = LinkedList()
    linkedList.insertLast("1")
    linkedList.insertLast("2")
    linkedList.insertLast("3")
    
    
    # Create a loop for testing 
    linkedList.head.next.next.next = linkedList.head; 
    #let's check and see !
    print(linkedList.has_cycle())
    

提交回复
热议问题