CIRCULAR LINKED LIST
A circular linked list is a data structure where the last node connects back to the first, forming a
loop. This structure allows for continuous traversal without any interruptions.
Circular linked lists are especially helpful for tasks like
Scheduling.
Managing playlists.
It is linked list where all the nodes are connected to form a circle. Unlike a regular linked list, which
ends with a node pointing to NULL, the last node in a circular linked list points back to the first node.
This means that you can keep traversing the list without ever reaching a NULL value.
Types of Circular Linked Lists
We can create a circular linked list from both singly linked lists and doubly linked lists. So, circular
linked list are basically of two types:
1. Circular Singly Linked List
In Circular Singly Linked List, each node has just one pointer called the “next” pointer. The next
pointer of last node points back to the first node and this results in forming a circle. In this type of
Linked list we can only move through the list in one direction.
2. Circular Doubly Linked List:
In circular doubly linked list, each node has two pointers prev and next, similar to doubly linked list.
The prev pointer points to the previous node and the next points to the next node. Here, in addition
to the last node storing the address of the first node, the first node will also store the address of
the last node.
Create/Declare a Node of Circular Linked List
struct Node
{
int data;
struct Node *next;
};
// Function to create a new node
struct Node *createNode(int value)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
Example of Creating a Circular Linked List
Here’s an example of creating a circular linked list with three nodes (2, 3, 4):
// Allocate memory for nodes
struct Node *first = (struct Node *)malloc(sizeof(struct Node));
struct Node *second =(struct Node *)malloc(sizeof(struct Node));
struct Node *last =(struct Node *)malloc(sizeof(struct Node));
// Initilize nodes
first->data = 2;
second->data = 3;
last->data = 4;
// Connect nodes
first->next = second;
second->next = last;
last->next = first;
Why have we taken a pointer that points to the last node instead of the first node?
For the insertion of a node at the beginning, we need to traverse the whole list. Also, for insertion at
the end, the whole list has to be traversed. If instead of the start pointer, we take a pointer to the
last node, then in both cases there won’t be any need to traverse the whole list. So insertion at the
beginning or at the end takes constant time, irrespective of the length of the list.
Operations on the Circular Linked list:
We can do some operations on the circular linked list similar to the singly and doubly linked list
which are:
Insertion
o Insertion at the empty list
o Insertion at the beginning
o Insertion at the end
o Insertion at the given position
Deletion
o Delete the first node
o Delete the last node
o Delete the node from any position
Searching
Insertion in Circular Singly Linked List
There are four main ways to add items:
Insertion in an empty list
Insertion at the beginning of the list
Insertion at the end of the list
Insertion at specific position in the list
Now, let’s look at the methods and steps for these four insertion operations.
Advantage of using a tail pointer instead of head pointer
For the insertion of a node at the beginning, we need to traverse the whole list. Also, for insertion at
the end, the whole list has to be traversed. If instead of the start pointer, we take a pointer to the
last node, then in both cases there won’t be any need to traverse the whole list. So insertion at the
beginning or at the end takes constant time, irrespective of the length of the list.
Insertion in the circular linked list:
Insertion is a fundamental operation in linked lists that involves adding a new node to the list. The
only extra step is connecting the last node to the first one. In the circular linked list mentioned
below, we can insert nodes in four ways:
1. Insertion in an empty List in the circular linked list
To insert a node in empty circular linked list, creates a new node with the given data, sets its next
pointer to point to itself, and updates the last pointer to reference this new node.
Step-by-step approach:
Check if last is not nullptr. If true, return last (the list is not empty).
Otherwise, Create a new node with the provided data.
o Set the new node’s next pointer to point to itself (circular link).
o Update last to point to the new node and return it.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* createNode(int value);
// Function to insert a node into an empty
// circular singly linked list
struct Node* insertInEmptyList(struct Node* last, int data)
{
if (last != NULL) return last;
// Create a new node
struct Node* newNode = createNode(data);
// Update last to point to the new node
last = newNode;
return last;
}
void printList(struct Node* last) {
if (last == NULL) return;
// Start from the head node
struct Node* head = last->next;
while (1) {
printf("%d ", head->data);
head = head->next;
if (head == last->next) break;
}
printf("\n");
}
struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = newNode;
return newNode;
}
int main() {
struct Node* last = NULL;
// Insert a node into the empty list
last = insertInEmptyList(last, 1);
// Print the list
printf("List after insertion: ");
printList(last);
return 0;
}