Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python Program To Detect A Loop In A Linked List
A linked list is said to have a loop when any node in the linked list is not pointing to NULL. The last node will be pointing to one of the previous nodes in the linked list, thus creating a loop. There will not be an end in a linked list that has a loop.
In the below example, the last node (node 5) is not pointing to NULL. Instead, it is pointing to node 3 and a loop is established. Hence, there is no end to the above linked list.
Floyd's Cycle Detection Algorithm (Two Pointers)
The most efficient way to detect a loop is using Floyd's Cycle Detection Algorithm, also known as the "tortoise and hare" algorithm ?
Both pointers initially point to the HEAD of the linked list.
The slow pointer moves one step at a time and the fast pointer moves two steps at a time.
If both pointers meet at the same node, then the linked list contains a loop.
If the fast pointer reaches NULL, then there is no loop in the linked list.
Example
Here's a complete implementation that creates a linked list with a loop and detects it ?
class Node:
def __init__(self, val):
self.val = val
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def insert_at_end(self, newVal):
newNode = Node(newVal)
if self.head == None:
self.head = newNode
return
temp = self.head
while temp.next:
temp = temp.next
temp.next = newNode
def print_list(self):
temp = self.head
if temp != None:
print("The linked list elements are:", end=" ")
while temp != None:
print(temp.val, end=" ")
temp = temp.next
print()
else:
print("The list is empty.")
def detect_loop(self):
if self.head == None:
return False
slow = self.head
fast = self.head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
print("A loop has been detected in the linked list")
return True
print("No loop detected in the linked list")
return False
# Create a linked list with a loop
linked_list = LinkedList()
linked_list.insert_at_end(1)
linked_list.insert_at_end(2)
linked_list.insert_at_end(3)
linked_list.insert_at_end(4)
linked_list.insert_at_end(5)
linked_list.print_list()
# Create a loop: make the last node point to the second node
linked_list.head.next.next.next.next.next = linked_list.head.next
# Detect the loop
linked_list.detect_loop()
The linked list elements are: 1 2 3 4 5 A loop has been detected in the linked list
Example Without Loop
Let's test the algorithm on a linked list without a loop ?
# Create a linked list without a loop normal_list = LinkedList() normal_list.insert_at_end(10) normal_list.insert_at_end(20) normal_list.insert_at_end(30) normal_list.print_list() normal_list.detect_loop()
The linked list elements are: 10 20 30 No loop detected in the linked list
How It Works
The algorithm works because if there's a loop, the fast pointer will eventually catch up to the slow pointer inside the loop. Think of it like two runners on a circular track the faster runner will eventually lap the slower one.
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | At most visits each node twice |
| Space | O(1) | Only uses two pointer variables |
Conclusion
Floyd's Cycle Detection Algorithm is an efficient way to detect loops in linked lists using two pointers. It has O(1) space complexity and O(n) time complexity, making it optimal for this problem.
