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
Circular linked lists in Javascript
A Circular Linked List is a variation of the standard linked list where the first element points to the last element and the last element points back to the first element, forming a circle. Both singly and doubly linked lists can be implemented as circular structures.
Node Structure
First, we define a Node class that contains data and a reference to the next node:
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
// Example of creating nodes
let node1 = new Node(10);
let node2 = new Node(20);
let node3 = new Node(30);
console.log("Node created:", node1.data);
Node created: 10
Circular Linked List Implementation
Here's a complete implementation of a circular linked list with essential operations:
class CircularLinkedList {
constructor() {
this.head = null;
this.size = 0;
}
// Insert at the beginning
insertAtBeginning(data) {
const newNode = new Node(data);
if (!this.head) {
this.head = newNode;
newNode.next = this.head; // Point to itself
} else {
// Find the last node
let current = this.head;
while (current.next !== this.head) {
current = current.next;
}
newNode.next = this.head;
current.next = newNode;
this.head = newNode;
}
this.size++;
}
// Insert at the end
insertAtEnd(data) {
const newNode = new Node(data);
if (!this.head) {
this.head = newNode;
newNode.next = this.head;
} else {
let current = this.head;
while (current.next !== this.head) {
current = current.next;
}
current.next = newNode;
newNode.next = this.head;
}
this.size++;
}
// Display all nodes
display() {
if (!this.head) {
console.log("List is empty");
return;
}
let current = this.head;
let result = [];
do {
result.push(current.data);
current = current.next;
} while (current !== this.head);
console.log("Circular List:", result.join(" -> ") + " -> (back to " + this.head.data + ")");
}
}
// Example usage
let cll = new CircularLinkedList();
cll.insertAtEnd(10);
cll.insertAtEnd(20);
cll.insertAtBeginning(5);
cll.display();
Circular List: 5 -> 10 -> 20 -> (back to 5)
Delete Operation
Deleting nodes in a circular linked list requires special handling:
class CircularLinkedList {
constructor() {
this.head = null;
this.size = 0;
}
insertAtEnd(data) {
const newNode = new Node(data);
if (!this.head) {
this.head = newNode;
newNode.next = this.head;
} else {
let current = this.head;
while (current.next !== this.head) {
current = current.next;
}
current.next = newNode;
newNode.next = this.head;
}
this.size++;
}
delete(data) {
if (!this.head) {
console.log("List is empty");
return;
}
// If deleting head node
if (this.head.data === data) {
if (this.head.next === this.head) {
// Only one node
this.head = null;
} else {
// Find last node
let current = this.head;
while (current.next !== this.head) {
current = current.next;
}
current.next = this.head.next;
this.head = this.head.next;
}
this.size--;
return;
}
// Delete non-head node
let current = this.head;
while (current.next !== this.head && current.next.data !== data) {
current = current.next;
}
if (current.next.data === data) {
current.next = current.next.next;
this.size--;
} else {
console.log("Node not found");
}
}
display() {
if (!this.head) {
console.log("List is empty");
return;
}
let current = this.head;
let result = [];
do {
result.push(current.data);
current = current.next;
} while (current !== this.head);
console.log("List:", result.join(" -> "));
}
}
// Example usage
let list = new CircularLinkedList();
list.insertAtEnd(10);
list.insertAtEnd(20);
list.insertAtEnd(30);
list.display();
list.delete(20);
list.display();
List: 10 -> 20 -> 30 List: 10 -> 30
Key Advantages and Use Cases
| Advantage | Use Case |
|---|---|
| Continuous traversal | Round-robin scheduling |
| No null pointers | Music playlist loops |
| Efficient insertion at beginning | Buffer implementations |
| Memory efficiency | Game turn management |
Key Points
- The last node's
nextpointer points back to the first node - No node has a
nullnext pointer (unlike linear linked lists) - Traversal must use a
do-whileloop to avoid infinite loops - Deletion requires updating the last node's pointer when deleting the head
- Useful for applications requiring circular iteration
Conclusion
Circular linked lists provide continuous traversal capabilities and eliminate null pointer handling. They're particularly useful for round-robin algorithms and applications requiring cyclic data structures.
