Explain the concept of a circular linked list. Describe its advantages and disadvantages compared to a singly linked list. Provide an example of a scenario where a circular linked list would be a suitable data structure, and write code snippets in Python or Java to demonstrate how to insert a node into a circular linked list and traverse the list. Explain how to detect if a circular linked list has a loop.
A circular linked list is a type of linked list where the last node points back to the first node, forming a circle. This is in contrast to a singly linked list, where the last node points to null
, or a doubly linked list, where the last node points to null
and each node has a pointer to the next and previous nodes.
Consider a music playlist that should loop continuously. A circular linked list is a suitable data structure for this, as it allows seamless looping from the last song back to the first song.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class CircularLinkedList:
def __init__(self):
self.head = None
def insert_at_beginning(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
new_node.next = self.head
else:
temp = self.head
while temp.next != self.head:
temp = temp.next
temp.next = new_node
new_node.next = self.head
self.head = new_node
def traverse(self):
if not self.head:
return
temp = self.head
while True:
print(temp.data, end=" -> ")
temp = temp.next
if temp == self.head:
break
print("...")
# Example usage
cll = CircularLinkedList()
cll.insert_at_beginning(3)
cll.insert_at_beginning(2)
cll.insert_at_beginning(1)
cll.traverse()
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
class CircularLinkedList {
Node head;
public CircularLinkedList() {
this.head = null;
}
public void insertAtBeginning(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
newNode.next = head;
} else {
Node temp = head;
while (temp.next != head) {
temp = temp.next;
}
temp.next = newNode;
newNode.next = head;
head = newNode;
}
}
public void traverse() {
if (head == null) {
return;
}
Node temp = head;
do {
System.out.print(temp.data + " -> ");
temp = temp.next;
} while (temp != head);
System.out.println("...");
}
public static void main(String[] args) {
CircularLinkedList cll = new CircularLinkedList();
cll.insertAtBeginning(3);
cll.insertAtBeginning(2);
cll.insertAtBeginning(1);
cll.traverse();
}
}
This algorithm uses two pointers, one moving slowly (tortoise) and one moving faster (hare). If there's a loop, the hare will eventually meet the tortoise.
def detect_loop(linked_list):
if not linked_list.head:
return False
slow_ptr = linked_list.head
fast_ptr = linked_list.head
while fast_ptr and fast_ptr.next:
slow_ptr = slow_ptr.next
fast_ptr = fast_ptr.next.next
if slow_ptr == fast_ptr:
return True
return False
Explanation:
slow_ptr
moves one node at a time.fast_ptr
moves two nodes at a time.fast_ptr
reaches the end (None), there is no loop.