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
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())