A circular linked list is a variation of a linked list where the last node points back to the first node, forming a circular structure. This structure has several advantages, such as efficient traversal and reduced overhead for operations. One of the key operations in managing such a data structure is deleting a node at a specific position. This process requires careful handling to maintain the integrity of the circular structure.
Below, we dive into the detailed procedure for deleting a node at a specific position in a circular linked list.
Table of Contents

Detailed Informative Table
Step | Description | Actions/Conditions | Outcome |
---|---|---|---|
1. Check if List is Empty | Determine if the circular linked list is empty. | – If last == nullptr , the list is empty.- Print: “List is empty, nothing to delete.”– Return nullptr . | No changes made to the list. The operation terminates. |
2. Handle Single-Node List | Check if the list contains only one node and delete it if the key matches. | – If last->next == last and last->data == key : 1. Delete the node. 2. Set last = nullptr . | The list becomes empty (nullptr ). |
3. Check if Head Node Matches | Handle the case where the first node (head) matches the key to be deleted. | – If last->next->data == key : 1. Update last->next to last->next->next . 2. Delete the head node. | The head is deleted, and the circular property is maintained. |
4. Traverse to Find Node | Traverse the list using two pointers (curr and prev ) to locate the node with the specified key. | – Start curr = last->next (head) and prev = last .- Loop until curr->data == key or the entire list is traversed. | Identifies the node to be deleted or confirms the key does not exist. |
5. Delete Found Node | Remove the found node by updating pointers. | – If curr->data == key : 1. Update prev->next = curr->next . 2. If curr == last , set last = prev . | The node is deleted, and the circular structure remains intact. |
6. Handle Node Not Found | Ensure no changes are made if the key is not found in the list. | – If curr traverses the entire list and no match is found: – Print: “Node with data [key] not found.” | No changes to the list. The structure remains as it was. |
7. Return Updated List | Return the modified list to reflect the changes made during the deletion process. | – Return the updated last pointer. | The list is updated, ensuring integrity and circularity are preserved. |
Understanding the Problem
When deleting a node in a circular linked list, we need to account for various cases, such as an empty list, a single-node list, or deleting specific nodes like the head or the last node. Each case must be addressed to ensure the list’s circular property remains intact. Let’s go step-by-step through the process, highlighting the necessary actions and conditions.
Step 1: Check if the List is Empty
The first step is to determine if the list is empty. In circular linked lists, this is represented by the condition where the pointer last
(or tail) is set to nullptr
.
- Scenario: If
last
isnullptr
, the list is empty, and no deletion is possible. - Action: Print an appropriate message like “List is empty, nothing to delete” and return
nullptr
to indicate the operation has no effect.
This ensures we do not attempt any operation on an invalid or non-existent data structure, preventing runtime errors.
Step 2: Handle the Single-Node Case
If the list contains only one node, this requires special attention. The single-node case can be identified when last->next
(the head of the list) points to itself.
- Scenario: If the data in the single node matches the key for deletion, we can safely remove it.
- Action:
- Delete the node.
- Set
last
tonullptr
to indicate the list is now empty.
This operation breaks the circular property because the single node is removed, but this is acceptable as the list becomes empty.
Step 3: Check if the Node to Delete is the Head
The head of a circular linked list is the first node, which can be accessed via last->next
. If the node to be deleted is the head, special adjustments are necessary:
- Scenario: If the head node’s data matches the key for deletion:
- Update
last->next
to point to the next node after the head. - Delete the current head node.
- Update
This ensures the circular structure remains intact while removing the head node.
Step 4: Traverse to Find the Node
For cases where the node to be deleted is neither the head nor the single node, we must traverse the list. Two pointers are utilized in this process:
curr
: Tracks the current node being examined.prev
: Tracks the previous node.
Steps to Traverse and Delete
- Start with
curr
set tolast->next
(the head). - Use
prev
to keep track of the node beforecurr
. - Traverse through the list while checking the data in
curr
against the key for deletion. - If a match is found:
- Update
prev->next
to skipcurr
, effectively removing it from the list. - If the deleted node is the last node, update
last
to point toprev
.
- Update
Step 5: Handle Node Not Found
If the entire list is traversed and the key does not match any node:
- Print an appropriate message like “Node with data [key] not found”.
- Ensure no modifications are made to the structure of the list.
Final Steps
Once the deletion process is complete:
- Return the updated
last
pointer. - Verify that the list’s circular property remains intact.
Example in Action
Let’s consider an example to see this process in practice:
- Initial List:
1 -> 2 -> 3 -> 4 -> (back to 1)
last
points to the node with value4
.
- Delete Node with Value
3
:- Traverse the list until the node with value
3
is found. - Update
prev->next
(node2
) to point to the node after3
(node4
). - If
3
is the last node, adjustlast
to point toprev
.
- Traverse the list until the node with value
- Updated List:
1 -> 2 -> 4 -> (back to 1)
Code Implementation In Multiple Programming Languages

C Programming
#include <stdio.h>
#include <stdlib.h>
// Define the structure of a node
struct Node {
int data; // Data stored in the node
struct Node* next; // Pointer to the next node in the circular linked list
};
// Function to delete a specific node by value
struct Node* deleteNode(struct Node* last, int value) {
if (last == NULL) { // Case 1: List is empty
printf("List is empty.\n");
return NULL;
}
struct Node *curr = last->next, *prev = last;
// Case 2: If the node to delete is the first node
if (curr->data == value) {
if (curr == last) { // Single node in the list
free(curr);
return NULL;
}
last->next = curr->next; // Skip the head node
free(curr);
return last;
}
// Case 3: Traverse the list to find the node to delete
do {
if (curr->data == value) { // Node found
prev->next = curr->next;
if (curr == last) // Update last if last node is deleted
last = prev;
free(curr);
return last;
}
prev = curr;
curr = curr->next;
} while (curr != last->next);
printf("Value %d not found in the list.\n", value);
return last;
}
// Function to print the circular linked list
void printList(struct Node* last) {
if (last == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = last->next;
do {
printf("%d ", temp->data);
temp = temp->next;
} while (temp != last->next);
printf("\n");
}
// Function to create a new node with the given value
struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
int main() {
struct Node* first = createNode(2);
first->next = createNode(3);
first->next->next = createNode(4);
struct Node* last = first->next->next;
last->next = first;
printf("Original list: ");
printList(last);
last = deleteNode(last, 3);
printf("List after deleting node 3: ");
printList(last);
return 0;
}
C++ Implementation
#include <iostream>
using namespace std;
// Define the structure of a node
struct Node {
int data; // Data stored in the node
Node* next; // Pointer to the next node in the circular linked list
};
// Function to delete a specific node by value
Node* deleteNode(Node* last, int value) {
if (last == nullptr) { // Case 1: List is empty
cout << "List is empty." << endl;
return nullptr;
}
Node *curr = last->next, *prev = last;
// Case 2: If the node to delete is the first node
if (curr->data == value) {
if (curr == last) { // Single node in the list
delete curr;
return nullptr;
}
last->next = curr->next; // Skip the head node
delete curr;
return last;
}
// Case 3: Traverse the list to find the node to delete
do {
if (curr->data == value) { // Node found
prev->next = curr->next;
if (curr == last) // Update last if last node is deleted
last = prev;
delete curr;
return last;
}
prev = curr;
curr = curr->next;
} while (curr != last->next);
cout << "Value " << value << " not found in the list." << endl;
return last;
}
// Function to print the circular linked list
void printList(Node* last) {
if (last == nullptr) {
cout << "List is empty." << endl;
return;
}
Node* temp = last->next;
do {
cout << temp->data << " ";
temp = temp->next;
} while (temp != last->next);
cout << endl;
}
// Function to create a new node with the given value
Node* createNode(int value) {
Node* newNode = new Node();
newNode->data = value;
newNode->next = nullptr;
return newNode;
}
int main() {
Node* first = createNode(2);
first->next = createNode(3);
first->next->next = createNode(4);
Node* last = first->next->next;
last->next = first;
cout << "Original list: ";
printList(last);
last = deleteNode(last, 3);
cout << "List after deleting node 3: ";
printList(last);
return 0;
}
C# Implementation
using System;
class Node {
public int Data; // Data stored in the node
public Node Next; // Pointer to the next node in the circular linked list
}
class CircularLinkedList {
public static Node DeleteNode(Node last, int value) {
if (last == null) { // Case 1: List is empty
Console.WriteLine("List is empty.");
return null;
}
Node curr = last.Next, prev = last;
// Case 2: If the node to delete is the first node
if (curr.Data == value) {
if (curr == last) { // Single node in the list
return null;
}
last.Next = curr.Next; // Skip the head node
return last;
}
// Case 3: Traverse the list to find the node to delete
do {
if (curr.Data == value) {
prev.Next = curr.Next;
if (curr == last) // Update last if last node is deleted
last = prev;
return last;
}
prev = curr;
curr = curr.Next;
} while (curr != last.Next);
Console.WriteLine($"Value {value} not found in the list.");
return last;
}
public static void PrintList(Node last) {
if (last == null) {
Console.WriteLine("List is empty.");
return;
}
Node temp = last.Next;
do {
Console.Write(temp.Data + " ");
temp = temp.Next;
} while (temp != last.Next);
Console.WriteLine();
}
public static Node CreateNode(int value) {
return new Node { Data = value, Next = null };
}
public static void Main() {
Node first = CreateNode(2);
first.Next = CreateNode(3);
first.Next.Next = CreateNode(4);
Node last = first.Next.Next;
last.Next = first;
Console.WriteLine("Original list: ");
PrintList(last);
last = DeleteNode(last, 3);
Console.WriteLine("List after deleting node 3: ");
PrintList(last);
}
}
Java Implementation
class Node {
int data; // Data stored in the node
Node next; // Pointer to the next node in the circular linked list
Node(int data) {
this.data = data;
this.next = null;
}
}
public class CircularLinkedList {
// Function to delete a specific node by value
public static Node deleteNode(Node last, int value) {
if (last == null) { // Case 1: List is empty
System.out.println("List is empty.");
return null;
}
Node curr = last.next, prev = last;
// Case 2: If the node to delete is the first node
if (curr.data == value) {
if (curr == last) { // Single node in the list
return null;
}
last.next = curr.next; // Skip the head node
return last;
}
// Case 3: Traverse the list to find the node to delete
do {
if (curr.data == value) {
prev.next = curr.next;
if (curr == last) // Update last if last node is deleted
last = prev;
return last;
}
prev = curr;
curr = curr.next;
} while (curr != last.next);
System.out.println("Value " + value + " not found in the list.");
return last;
}
// Function to print the circular linked list
public static void printList(Node last) {
if (last == null) {
System.out.println("List is empty.");
return;
}
Node temp = last.next;
do {
System.out.print(temp.data + " ");
temp = temp.next;
} while (temp != last.next);
System.out.println();
}
// Function to create a new node
public static Node createNode(int value) {
return new Node(value);
}
public static void main(String[] args) {
// Step 1: Create nodes and form a circular linked list
Node first = createNode(2);
first.next = createNode(3);
first.next.next = createNode(4);
Node last = first.next.next;
last.next = first; // Complete the circular link
// Step 2: Print the original list
System.out.println("Original list:");
printList(last);
// Step 3: Delete a node with value 3
last = deleteNode(last, 3);
// Step 4: Print the list after deletion
System.out.println("List after deleting node 3:");
printList(last);
}
}
JavaScript Implementation
class Node {
constructor(data) {
this.data = data; // Data stored in the node
this.next = null; // Pointer to the next node in the circular linked list
}
}
class CircularLinkedList {
static deleteNode(last, value) {
if (!last) { // Case 1: List is empty
console.log("List is empty.");
return null;
}
let curr = last.next, prev = last;
// Case 2: If the node to delete is the first node
if (curr.data === value) {
if (curr === last) { // Single node in the list
return null;
}
last.next = curr.next; // Skip the head node
return last;
}
// Case 3: Traverse the list to find the node to delete
do {
if (curr.data === value) {
prev.next = curr.next;
if (curr === last) // Update last if last node is deleted
last = prev;
return last;
}
prev = curr;
curr = curr.next;
} while (curr !== last.next);
console.log(`Value ${value} not found in the list.`);
return last;
}
static printList(last) {
if (!last) {
console.log("List is empty.");
return;
}
let temp = last.next;
let result = "";
do {
result += temp.data + " ";
temp = temp.next;
} while (temp !== last.next);
console.log(result.trim());
}
static createNode(value) {
return new Node(value);
}
}
// Main program
let first = CircularLinkedList.createNode(2);
first.next = CircularLinkedList.createNode(3);
first.next.next = CircularLinkedList.createNode(4);
let last = first.next.next;
last.next = first; // Complete the circular link
console.log("Original list:");
CircularLinkedList.printList(last);
last = CircularLinkedList.deleteNode(last, 3);
console.log("List after deleting node 3:");
CircularLinkedList.printList(last);
Python Implementation
class Node:
def __init__(self, data):
self.data = data # Data stored in the node
self.next = None # Pointer to the next node in the circular linked list
def delete_node(last, value):
if not last: # Case 1: List is empty
print("List is empty.")
return None
curr = last.next
prev = last
# Case 2: If the node to delete is the first node
if curr.data == value:
if curr == last: # Single node in the list
return None
last.next = curr.next # Skip the head node
return last
# Case 3: Traverse the list to find the node to delete
while curr != last.next:
if curr.data == value:
prev.next = curr.next
if curr == last: # Update last if last node is deleted
last = prev
return last
prev = curr
curr = curr.next
print(f"Value {value} not found in the list.")
return last
def print_list(last):
if not last:
print("List is empty.")
return
temp = last.next
result = []
while True:
result.append(temp.data)
temp = temp.next
if temp == last.next:
break
print(" ".join(map(str, result)))
def create_node(value):
return Node(value)
# Main program
first = create_node(2)
first.next = create_node(3)
first.next.next = create_node(4)
last = first.next.next
last.next = first # Complete the circular link
print("Original list:")
print_list(last)
last = delete_node(last, 3)
print("List after deleting node 3:")
print_list(last)
Output
Original list:
2 3 4
List after deleting node 3:
2 4
Complexities
- Time Complexity: O(n) (in the worst case, traverse the list to find the node).
- Space Complexity: O(1) (no additional memory used).
Advantages of Proper Handling
- Maintains Circular Structure: The circular property ensures efficient traversal and minimizes the chance of dangling pointers.
- Robustness: By addressing edge cases (empty list, single node, etc.), the algorithm avoids common pitfalls.
- Efficiency: Traversing the list and updating pointers are straightforward operations with
O(n)
complexity.
Conclusion
Deleting a specific node from a circular linked list is a fundamental operation that requires attention to various scenarios. Proper handling ensures the list remains functional and adheres to its circular nature. By systematically addressing edge cases and carefully managing pointer updates, this operation can be performed seamlessly, enhancing the flexibility and utility of the circular linked list structure.
Related Articles
- Introduction to Circular Linked Lists: A Comprehensive Guide
- Understanding Circular Singly Linked Lists: A Comprehensive Guide
- Circular Doubly Linked List: A Comprehensive Guide
- Insertion in Circular Singly Linked List: A Comprehensive Guide
- Insertion in an Empty Circular Linked List: A Detailed Exploration
- Insertion at the Beginning in Circular Linked List: A Detailed Exploration
- Insertion at the End of a Circular Linked List: A Comprehensive Guide
- Insertion at a Specific Position in a Circular Linked List: A Detailed Exploration
- Deletion from a Circular Linked List: A Comprehensive Guide
- Deletion from the Beginning of a Circular Linked List: A Detailed Exploration
- Deletion at Specific Position in Circular Linked List: A Detailed Exploration
- Deletion at the End of a Circular Linked List: A Comprehensive Guide
- Searching in a Circular Linked List: A Comprehensive Exploration
Read More Articles
- Data Structure (DS) Array:
- Why the Analysis of Algorithms is Important?
- Worst, Average, and Best Case Analysis of Algorithms: A Comprehensive Guide
- Understanding Pointers in C Programming: A Comprehensive Guide
- Understanding Arrays in Data Structures: A Comprehensive Exploration
- Memory Allocation of an Array: An In-Depth Comprehensive Exploration
- Understanding Basic Operations in Arrays: A Comprehensive Guide
- Understanding 2D Arrays in Programming: A Comprehensive Guide
- Mapping a 2D Array to a 1D Array: A Comprehensive Exploration
- Data Structure Linked List:
- Understanding Linked Lists in Data Structures: A Comprehensive Exploration
- Types of Linked List: Detailed Exploration, Representations, and Implementations
- Understanding Singly Linked Lists: A Detailed Exploration
- Understanding Doubly Linked List: A Comprehensive Guide
- Operations of Doubly Linked List with Implementation: A Detailed Exploration
- Insertion in Doubly Linked List with Implementation: A Detailed Exploration
- Inserting a Node at the beginning of a Doubly Linked List: A Detailed Exploration
- Inserting a Node After a Given Node in a Doubly Linked List: A Detailed Exploration
- Inserting a Node Before a Given Node in a Doubly Linked List: A Detailed Exploration
- Inserting a Node at a Specific Position in a Doubly Linked List: A Detailed Exploration
- Inserting a New Node at the End of a Doubly Linked List: A Detailed Exploration
- Deletion in a Doubly Linked List with Implementation: A Comprehensive Guide
- Deletion at the Beginning in a Doubly Linked List: A Detailed Exploration
- Deletion after a given node in Doubly Linked List: A Comprehensive Guide
- Deleting a Node Before a Given Node in a Doubly Linked List: A Detailed Exploration
- Deletion at a Specific Position in a Doubly Linked List: A Detailed Exploration
- Deletion at the End in Doubly Linked List: A Comprehensive Exploration
- Introduction to Circular Linked Lists: A Comprehensive Guide
- Understanding Circular Singly Linked Lists: A Comprehensive Guide
- Circular Doubly Linked List: A Comprehensive Guide
- Insertion in Circular Singly Linked List: A Comprehensive Guide
- Insertion in an Empty Circular Linked List: A Detailed Exploration
- Insertion at the Beginning in Circular Linked List: A Detailed Exploration
- Insertion at the End of a Circular Linked List: A Comprehensive Guide
- Insertion at a Specific Position in a Circular Linked List: A Detailed Exploration
- Deletion from a Circular Linked List: A Comprehensive Guide
- Deletion from the Beginning of a Circular Linked List: A Detailed Exploration
- Deletion at Specific Position in Circular Linked List: A Detailed Exploration
- Deletion at the End of a Circular Linked List: A Comprehensive Guide
- Searching in a Circular Linked List: A Comprehensive Exploration
Frequently Asked Questions (FAQs)
What is a Circular Linked List, and how does it differ from other linked lists?
A circular linked list is a variation of a linked list where the last node is connected back to the first node, forming a circular structure. Unlike a singly linked list, where the last node points to nullptr
, a circular linked list eliminates the need for a null pointer at the end. This structure allows for continuous traversal of the list and is particularly useful in scenarios where the list needs to be repeatedly accessed, such as task scheduling or implementing buffers. The circular structure provides unique challenges, especially during operations like deletion, as breaking the circular link can lead to data inconsistency.
Why is deletion at a specific position more complex in Circular Linked Lists?
Deletion in a circular linked list requires careful handling because the circular nature must be preserved. If a node is removed, the pointers of the adjacent nodes need to be updated to maintain the loop. Unlike a singly linked list, where reaching the end node terminates traversal, a circular linked list has no natural end. Thus, traversal must account for looping back to the head node. Additionally, edge cases like deleting the head, the last node, or the only node in the list introduce additional complexity.
How can we identify if the Circular Linked List is empty before deletion?
An empty circular linked list is identified by checking if the pointer last
is set to nullptr
. This pointer, which typically points to the last node in the list, serves as an entry point to traverse the circular structure. If last
is nullptr
, no nodes exist in the list, and a deletion operation cannot proceed. In such cases, an appropriate message like “List is empty, nothing to delete” should be printed to inform the user.
What happens if we attempt to delete from an empty Circular Linked List?
Attempting to delete from an empty circular linked list has no effect because there are no nodes to remove. The operation should handle this gracefully by printing a message like “List is empty, nothing to delete” and returning nullptr
. This avoids runtime errors and ensures the program’s stability. It’s essential to include this check at the beginning of the deletion function to prevent unnecessary operations.
How is a single-node deletion handled in a Circular Linked List?
When the circular linked list contains only one node, it requires special attention during deletion. The single-node condition is verified when last->next == last
, indicating the head and last nodes are the same. If the node’s data matches the key:
- The node is deleted.
- The pointer
last
is set tonullptr
to signify an empty list. This case is unique because removing the only node effectively breaks the circular structure, leaving the list empty.
How do you delete the head node in a Circular Linked List?
The head node in a circular linked list is the first node, accessed via last->next
. If the head node matches the key:
- Update
last->next
to point to the second node (last->next->next
). - Delete the current head node. This ensures that the new head is properly connected to the rest of the list, maintaining the circular link. Deleting the head is slightly more complex than deleting other nodes because it involves directly modifying the pointer in the
last
node.
What is the role of the prev
and curr
pointers during deletion?
The prev
and curr
pointers play crucial roles during traversal to locate the node to be deleted:
curr
tracks the current node being examined.prev
keeps track of the node precedingcurr
. When the node with the specified key is found:prev->next
is updated to skipcurr
.- If
curr
is the last node,last
is updated to point toprev
. This two-pointer technique ensures that the list remains intact even after the node is removed.
How do you delete the last node in a Circular Linked List?
If the node to be deleted is the last node, additional steps are necessary:
- Traverse the list using
prev
andcurr
untilcurr == last
. - Update
prev->next
to point to the head node (last->next
). - Set
last
toprev
. - Delete the node. This approach ensures the last node is removed while preserving the circular structure of the list.
What happens if the key is not found in the Circular Linked List?
If the key to be deleted is not found in the list, no changes are made to the structure. After traversing the entire list:
- Print a message like “Node with data [key] not found.”
- Ensure all pointers remain unchanged. This behavior prevents unintended modifications and confirms that the operation was unsuccessful due to the key’s absence.
How does the circular structure remain intact after a node is deleted?
The circular structure is preserved by carefully updating pointers during deletion:
- For the head node,
last->next
is updated. - For other nodes,
prev->next
skips the deleted node. - For the last node,
last
is reassigned toprev
. These steps ensure that no node points to a deleted node and that traversal remains seamless.
What is the time complexity of deleting a node in a Circular Linked List?
The time complexity of deleting a node in a circular linked list is O(n), where n
is the number of nodes in the list. This is because, in the worst case, the algorithm needs to traverse the entire list to find the node with the matching key. The pointer updates after finding the node take constant time, i.e., O(1).
Why is updating the last
pointer crucial during deletion?
The last
pointer plays a pivotal role in maintaining the circular nature of the list. If the node being deleted is the last node:
last
must be updated to point to the previous node.- This ensures the new last node’s
next
pointer links back to the head. Failure to updatelast
would break the circular link, causing traversal issues.
What precautions should be taken during deletion in a Circular Linked List?
Precautions during deletion include:
- Checking if the list is empty (
last == nullptr
). - Handling edge cases like single-node lists and deleting the head or last node.
- Ensuring all pointers are updated correctly to maintain circularity.
- Traversing the list carefully to avoid infinite loops.
What are the advantages of a Circular Linked List in deletion operations?
The circular linked list offers several advantages:
- Continuous traversal eliminates the need for additional conditions to check the end.
- Deletion of the head or last node is straightforward with proper pointer management.
- Circularity allows efficient implementation of algorithms like buffering and scheduling.
Can we implement deletion in a Circular Linked List using recursion?
Yes, deletion in a circular linked list can be implemented using recursion. However, recursion introduces additional complexity:
- Base Case: Handle empty list or single-node deletion.
- Recursive Step: Traverse nodes until the key is found, updating pointers along the way. While recursion is possible, iterative methods are generally preferred for simplicity and to avoid stack overflow in large lists.