Circular Linked list
Circular linked list is a list where all nodes are connected to
form a circle. In circular linked list, there is no NULL node at the end. A
circular linked list can be a singly circular linked list or doubly linked
list.
In the above figure, the node A is a head node and all the node is linked and there is no Null node like
Singly Linked List.
Implementation
To implement a Circular Singly Linked List, we take an external pointer that points to the last node of the list. If we have a pointer, pointing to the last node of the list, then last-> next will be the first node.
The pointer Last points to the node Q and last->next points to
the node P.
Why
we have taken the pointer that points to the last node of the list instead of
the first node?
While inserting the new node to the Circular Linked list in the
beginning of the list (head), we need to traverse the whole list, if it is
pointing the head node. And also for inserting the node at the end, the whole
list has to be traversed. Hence, the complexity is high as we traverse the
whole list for inserting the node at the beginning and at the end. For better
solution, we always point the pointer to the last node of the list. Hence
insertion at the beginning and at the end, always take constant time
irrespective of the length of the circular list.
Insertion
The node can be inserted in Circular linked list in three ways such as:
Insertion
in an empty list
While inserting a node in an empty list, last pointer will be
NULL. After inserting a node A, then the last pointer points to the node A.
Function to insert node in an empty list,
struct Node *addToEmpty(struct Node *tail, int data) { // If the list is not empty if(tail != NULL) { return tail; } //Create a node dynamically tail = (struct Node *)malloc(sizeof(struct Node *)); //Assign the data tail->data = data; //As there is only one node, we point the single node to itself tail->next = tail; return tail; }
In the above code, the start node and the tail node is same, as we
added to the empty circular linked list.
Insertion
at the beginning of the list
To insert a node at the beginning of the list, follow the below steps:
Function to insert node in the beginning of the circular linked list,
struct Node *addBegin(struct Node *tail, int data) { if (tail == NULL) return addToEmpty(tail, data); //Create a node dynamically. struct Node *temp = (struct Node *)malloc(sizeof(struct Node)); //Assigning the data temp->data = data; //Adjusting the links temp->next = tail->next; tail->next = temp; return tail; }
In the above code, the new node is inserted at the beginning and
tail pointer remains same after insertion.
Insertion
at the end of the List
To insert a node at the end of the list, follow the below steps:
Function to insert the new node at the end of the list:
struct Node *addEnd(struct Node *tail, int data) { if (tail == NULL) return addToEmpty(tail, data); //Create a node dynamically. struct Node *temp = (struct Node *)malloc(sizeof(struct Node)); //Assign the data temp->data = data; //Adjusting the links temp->next = tail->next; tail->next = temp; tail = temp; return tail; }
In the above code, we added the new node at the end of the list
and the last pointer points to the newly added node.
Inserting
in between the nodes
To insert a node after the given node, follow the below steps:
In the below figure, we add node 15, after node 10.
The below function is used to insert the number after the given number:
struct Node *addAfter(struct Node *tail, int data, int search) { if(tail == NULL) return NULL; struct Node *temp, *p; p = tail->next; //Search the given number do { if(p->data == search) { //Create a node dynamically temp = (struct Node *)malloc(sizeof(struct Node)); //Assigning the data temp->data = data; //Adjusting the links temp->next = p->next; p->next = temp; if(p == tail) tail = temp; return tail; } p = p->next; } while (p != tail->next); printf("The given item is not present in the list"); return tail; }
In the above code, the variable “search” is the item given to insert after the data.
Circular Linked List Deletion
This is similar to deletion in Singly linked list. The node to be
deleted will be given and reassign the links. The main step is to free the
memory space for the deleted linked list.
In the below figure, the node to be deleted is given (which is
30). The head pointer points to node 10. Here two pointers namely curr and prev
are used while traversing the list, the curr pointer points to current node and
the pre pointer points to the previous of the current node. While deleting the
current node, using the prev node pointer, the reassigning of links can be
done.
Below is the code to delete a node from the circular linked list.
void deleteNode(struct Node* head, int key) { if (head == NULL) return; // Find the required node struct Node *curr = head, *prev; while (curr->data != key) { if (curr->next == head) { printf("\nGiven node is not found in the list"); break; } prev = curr; curr = curr->next; } // Check if node is only node if (curr->next == head) { head = NULL; free(curr); return; } // If more than one node, check if // it is first node if (curr == head) { prev = head; while (prev->next != head) prev = prev->next; head = curr->next; prev->next = head; free(curr); } // check if node is last node else if (curr->next == head) { prev->next = head; free(curr); } else { prev->next = curr->next; free(curr); } }
The
following steps are considered in the above code:
Step 1: If list is empty
Step
2: If list is not empty.
Advantages of Circular Linked List: