C Program to Implement Circular Linked List
Last Updated :
15 Jul, 2024
A linked list is a dynamic data structure where elements are not stored in contiguous memory locations but linked using pointers. In a circular linked list, the last node points back to the first node instead of pointing to NULL, forming a circle.
In this article, we will learn how to implement the circular linked list in C++ along with its basic operations.
What is a Circular Linked List?
A circular linked list is a type of linked list where the last node of the list points back to the first node instead of pointing to NULL. This circular linking makes traversal of the list from any point possible and eliminates the need to maintain a separate pointer for the head and tail of the list.
In the above diagram, last node pointer back to first node, creating the circular link. This organization allows for the seamless transitions from the end of list back to the beginning and it can be enabling the continuous iteration over the lists elements.
Representation of Circular Linked List in C
In C, a circular linked list is represented using a Node structure that contains data and a pointer to the next node:
struct Node {
int data;
struct Node* next;
};
Implementation of Circular Linked List in C
To implement a circular linked list in C, we can define functions for basic operations such as insertion, deletion, traversal, and searching. Here’s how we can create and manipulate a circular linked list:
Basic Operations on Circular Linked List
Following are the basic operations on the circular linked list in C++:
1. Insertion
Insertion in the circular linked list can be performed at the various positions: the beginning, the end or after the specific node. Each insertion operation has its own specific steps and considerations to the maintain the circular structure.
Operation | Definition | Time Complexity | Space Complexity |
---|
Insertion at the end | Adding the new node at the end of circular linked list. | O(n) | O(1) |
---|
Insertion at the Beginning | Adding the new node at the beginning of the circular linked list. | O(n) | O(1) |
---|
Deletion from the Specific Position | Adding the new node at the given position | O(n) | O(1) |
---|
Implementation of InsertAtBegin
To insert a node at the beginning of a circular linked list:
- Create a new node with the given data.
- If the list is empty, set the new node to itself and make it the head node.
- If the list is not empty, traverse to the last node and update its next pointer to point to the new node. Then update the head pointer to the new node.'
Implementation of InsertAtEnd
To insert a node at the end of a circular linked list:
- Create a new node with the given data.
- If the list is empty, set the new node to itself and make it the head node.
- If the list is not empty, traverse to the last node.
- Set the last node's next pointer to the new node.
- Set the new node's next pointer to the head to maintain circularity.
Implementation of InsertAtSpecificPosition
To insert a node at a specific position in a circular linked list:
- Create a new node with the given data.
- If the list is empty and position is 0, set the new node to itself and make it the head node.
- Traverse to the node just before the desired position.
- Insert the new node by adjusting pointers.
2. Deletion
Deletion can be performed at the various positions: from the beginning, the end or the specific node. Each deletion operation must ensure the structure can be maintained by the updating pointers appropriately.
Operation | Definition | Time Complexity | Space Complexity |
---|
Deletion from the Beginning | Removing the first node of circular linked list. | O(n) | O(1) |
---|
Deletion from the End | Removing the last node of circular linked list. | O(n) | O(1) |
---|
Deletion from the Specific Position | Remove the element from the given position | O(n) | O(1) |
---|
Implementation of DeleteFromBeginning
To delete a node from the beginning of a circular linked list:
- If the list is empty, return.
- If the list has only one node, delete it and set head to NULL.
- Traverse to the last node and update its next pointer.
- Free the memory allocated to the node to be deleted.
Implementation of DeleteFromEnd
To delete a node from the end of a circular linked list:
- If the list is empty, return.
- If the list has only one node, delete it and set head to NULL.
- Traverse to the second last node and update its next pointer to NULL.
- Free the memory allocated to the last node.
Implementation of DeleteFromSpecificPosition
To delete a node from a specific position in a circular linked list:
- If the list is empty, return.
- Traverse to the node just before the desired position.
- Adjust pointers to skip the node to be deleted.
- Free the memory allocated to the node to be deleted.
3. Traversal
Traversing the circular linked list means visiting the each node starting from any node and continuing until all the nodes have been visited at the least once. this operation can typically starts at the head and continuous until the head is encountered again.
Implementation of Traversal
- Check if list is empty then if it is return.
- Initialize the temporary pointer to the head.
- Loop through the list starting from head and print the each nodes data.
- Continue until the pointer reaches back to head.
4. Search
To search for a node with a given key in a circular linked list:
- Start from the head node.
- Traverse each node and compare its data with the given key until the key is found or you reach the head again.
Program to Implement Circular Linked List in C
C
#include <stdio.h>
#include <stdlib.h>
// Node structure
struct Node {
int data;
struct Node* next;
};
// Function to create a new node
struct Node* createNode(int data)
{
struct Node* newNode
= (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// Function to insert a node at the beginning
void insertAtBeginning(struct Node** head, int data)
{
struct Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
newNode->next = *head;
}
else {
struct Node* temp = *head;
while (temp->next != *head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = *head;
*head = newNode;
}
}
// Function to insert a node at the end
void insertAtEnd(struct Node** head, int data)
{
struct Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
newNode->next = *head;
}
else {
struct Node* temp = *head;
while (temp->next != *head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = *head;
}
}
// Function to insert a node at a specific position
void insertAtPosition(struct Node** head, int data,
int position)
{
struct Node* newNode = createNode(data);
if (*head == NULL && position == 0) {
*head = newNode;
newNode->next = *head;
}
else if (position == 0) {
insertAtBeginning(head, data);
}
else {
struct Node* temp = *head;
int i = 0;
while (i < position - 1) {
temp = temp->next;
i++;
}
newNode->next = temp->next;
temp->next = newNode;
}
}
// Function to delete a node from the beginning
void deleteFromBeginning(struct Node** head)
{
if (*head == NULL) {
return;
}
else if ((*head)->next == *head) {
free(*head);
*head = NULL;
}
else {
struct Node* temp = *head;
while (temp->next != *head) {
temp = temp->next;
}
temp->next = (*head)->next;
struct Node* toDelete = *head;
*head = (*head)->next;
free(toDelete);
}
}
// Function to delete a node from the end
void deleteFromEnd(struct Node** head)
{
if (*head == NULL) {
return;
}
else if ((*head)->next == *head) {
free(*head);
*head = NULL;
}
else {
struct Node* secondLast = *head;
while (secondLast->next->next != *head) {
secondLast = secondLast->next;
}
struct Node* last = secondLast->next;
secondLast->next = *head;
free(last);
}
}
// Function to delete a node from a specific position
void deleteAtPosition(struct Node** head, int position)
{
if (*head == NULL) {
return;
}
else if (position == 0) {
deleteFromBeginning(head);
}
else {
struct Node* temp = *head;
int i = 0;
while (i < position - 1) {
temp = temp->next;
i++;
}
struct Node* toDelete = temp->next;
temp->next = temp->next->next;
free(toDelete);
}
}
// Function to traverse and print the circular linked list
void traverse(struct Node* head)
{
if (head == NULL) {
return;
}
struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("HEAD\n");
}
// Function to search for a node with a given key
int search(struct Node* head, int key)
{
if (head == NULL) {
return 0;
}
struct Node* temp = head;
do {
if (temp->data == key) {
return 1; // Key found
}
temp = temp->next;
} while (temp != head);
return 0; // Key not found
}
// Driver program
int main()
{
struct Node* head = NULL;
// Insertion
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtBeginning(&head, 5);
insertAtPosition(&head, 15, 2);
// Traversal
printf("Circular Linked List: ");
traverse(head);
// Deletion
deleteFromEnd(&head);
deleteAtPosition(&head, 1);
// Traversal after deletion
printf("Circular Linked List after deletion: ");
traverse(head);
// Searching
int key = 10;
if (search(head, key)) {
printf("Element %d is found in the linked list.\n",
key);
}
else {
printf(
"Element %d is not found in the linked list.\n",
key);
}
return 0;
}
OutputCircular Linked List: 5 -> 10 -> 15 -> 20 -> HEAD
Circular Linked List after deletion: 5 -> 15 -> HEAD
Element 10 is not found in the linked list.
Applications of Circular Linked List
- Round Robin Scheduling: It can be used in the operating system to schedule a process in the cyclic manner.
- FIFO Buffers: It can be used in networking for the buffer management.
- Music Player Playlists: It can be used to cycle through the songs in a playlist.
Related Articles:
Similar Reads
C Programming Language Tutorial C is a general-purpose mid-level programming language developed by Dennis M. Ritchie at Bell Laboratories in 1972. It was initially used for the development of UNIX operating system, but it later became popular for a wide range of applications. Today, C remains one of the top three most widely used
5 min read
Non-linear Components In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
Spring Boot Tutorial Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Class Diagram | Unified Modeling Language (UML) A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Steady State Response In this article, we are going to discuss the steady-state response. We will see what is steady state response in Time domain analysis. We will then discuss some of the standard test signals used in finding the response of a response. We also discuss the first-order response for different signals. We
9 min read
Backpropagation in Neural Network Back Propagation is also known as "Backward Propagation of Errors" is a method used to train neural network . Its goal is to reduce the difference between the modelâs predicted output and the actual output by adjusting the weights and biases in the network.It works iteratively to adjust weights and
9 min read
Polymorphism in Java Polymorphism in Java is one of the core concepts in object-oriented programming (OOP) that allows objects to behave differently based on their specific class type. The word polymorphism means having many forms, and it comes from the Greek words poly (many) and morph (forms), this means one entity ca
7 min read
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc() In C, a variable defined in a function is stored in the stack memory. The requirement of this memory is that it needs to know the size of the data to memory at compile time (before the program runs). Also, once defined, we can neither change the size nor completely delete the memory.To resolve this,
9 min read
3-Phase Inverter An inverter is a fundamental electrical device designed primarily for the conversion of direct current into alternating current . This versatile device , also known as a variable frequency drive , plays a vital role in a wide range of applications , including variable frequency drives and high power
13 min read
What is Vacuum Circuit Breaker? A vacuum circuit breaker is a type of breaker that utilizes a vacuum as the medium to extinguish electrical arcs. Within this circuit breaker, there is a vacuum interrupter that houses the stationary and mobile contacts in a permanently sealed enclosure. When the contacts are separated in a high vac
13 min read