Circular Linked List in C

What is circular linked list in C?

A Circular Linked List in C is a collection of elements connected together with the help of pointers. Such that each node contains a data value and addresses to the next node in the link. Where the last link of the circular Linked list has the address of the first node.

Key Characteristics:

  • No node in the list has a NULL next pointer.
  • Useful when you want to cycle through elements repeatedly, like in a game or round-robin scheduler.
  • The list can be singly or doubly circular, but the most basic form is singly circular.
Circular Linked List in C with head and next node

Why circular linked list?

As we know that singly linked list and doubly linked list are already present in there in data structure and algorithm then what is the need of circular linked list?

When we want to access the things in a loop repeatedly. Circular Linked List is ideal so that, whenever we reach the last node we can restart operations again by directly reaching the first node from the last node itself.

Circular Linked List in C Structure
Circular Linked List in C

Structure of Circular linked list

Circular linked can be of both singly and doubly types. So they can be defined in a program by using the following set of code.

Advantages of circular linked list in C

  1. Any node of the list can act as the head as the list does not end.
  2. Access to the first node from the last node is easy and time-saving.
  3. Queues can be easily implemented with a circular linked list.
  4. We can traverse the whole list from any node.

Implementation of Circular Linked List in C using basic operation

Here is an optimized C program to implement a Circular Linked List with basic operations like:

  • Creating a circular linked list
  • Inserting at the end
  • Deleting a node
  • Displaying the list

Code(In C laguage):

Run

#include <stdio.h>
#include <stdlib.h>

// Define Node structure
struct Node {
int data;
struct Node* next;
};

// Create a new node with given data
struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}

// Insert at the end
void insertEnd(struct Node** head, int value) {
struct Node* newNode = createNode(value);

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;
}
}

// Delete a node by value
void deleteNode(struct Node** head, int key) {
if (*head == NULL)
return;

struct Node *curr = *head, *prev = NULL;

// Deleting the head node
if (curr->data == key) {
if (curr->next == *head) {
free(curr);
*head = NULL;
return;
}

struct Node* last = *head;
while (last->next != *head)
last = last->next;

last->next = curr->next;
*head = curr->next;
free(curr);
return;
}

// Find node to delete
do {
prev = curr;
curr = curr->next;
} while (curr != *head && curr->data != key);

if (curr->data == key) {
prev->next = curr->next;
free(curr);
}
}

// Display the circular linked list
void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(head)\n");
}

// Main function
int main() {
struct Node* head = NULL;

// Insert values
insertEnd(&head, 5);
insertEnd(&head, 15);
insertEnd(&head, 25);
insertEnd(&head, 35);

printf("Initial Circular Linked List:\n");
display(head);

// Delete 25
deleteNode(&head, 25);
printf("\nAfter deleting 25:\n");
display(head);

// Delete 5
deleteNode(&head, 5);
printf("\nAfter deleting 5:\n");
display(head);

return 0;
}

Output:

Initial Circular Linked List:
5 -> 15 -> 25 -> 35 -> (head)

After deleting 25:
5 -> 15 -> 35 -> (head)

After deleting 5:
15 -> 35 -> (head)

Explanation:

  • We created a circular linked list with values 5, 15, 25, 35.
  • When we delete 25, it’s removed from the middle.
  • When we delete 5, it’s the head node, so we update the head and reconnect the last node to the new head.
  • display() shows how the list loops back to the start by ending with (head).

Operation on circular linked list

We can perform the following operations on a circular linked list.

  • Insertion
    • Inserting at Beginning of the list.
    • Inserting at End of the list.
    • Insert at a Specific location in the list.
  • Deletion
    • Deleting from the Beginning of the list.
    • Deleting from End of the list.
    • Deleting a Specific Node from the list
  • Traversal

Code For Insertion At The Beginning In Circular Linked List

Run
#include<stdio.h>
#include<stdlib.h>

struct Node
{
  int data;
  struct Node *next;
};

void insertStart (struct Node **head, int data)
{
  struct Node *newNode = (struct Node *) malloc (sizeof (struct Node));
  newNode->data = data;

  // if its the first node being entered
  if (*head == NULL)
    {
      *head = newNode;
      (*head)->next = *head;
      return;
    }

  // if LL already as >=1 node
  struct Node *curr = *head;

  // traverse till last node in LL
  while (curr->next != *head)
    {
      curr = curr->next;
    }
  // assign LL's last node's next as this new node
  curr->next = newNode;

  // assign newNode's next as current head
  newNode->next = *head;

  // change head to this new node
  *head = newNode;
}

void display (struct Node *head)
{
  // if there are no node in LL
  if (head == NULL)
    return;

  struct Node *temp = head;

  //need to take care of circular structure of LL
  do
    {
      printf ("%d ", temp->data);
      temp = temp->next;

    }
  while (temp != head);
  printf ("\n");
}

int main ()
{

  struct Node *head = NULL;

  printf ("Linked List: ");
  insertStart (&head, 6);
  insertStart (&head, 5);
  insertStart (&head, 4);
  insertStart (&head, 3);
  insertStart (&head, 2);
  insertStart (&head, 1);
  display (head);

  return 0;
}

Output

Linked List: 1 2 3 4 5 6 

Code For Insertion At The End In Circular Linked List

Run

#include<stdio.h>
#include<stdlib.h>

struct Node
{
  int data;
  struct Node *next;
};

void insertLast (struct Node **head, int data)
{
  struct Node *newNode = (struct Node *) malloc (sizeof (struct Node));
  newNode->data = data;

  // if its the first node being entered
  if (*head == NULL)
    {
      *head = newNode;
      (*head)->next = *head;
      return;
    }

  // if LL already as >=1 node
  struct Node *curr = *head;

  // traverse till last node in LL
  while (curr->next != *head)
    {
      curr = curr->next;
    }

  // assign LL's current last node's next as this new node
  curr->next = newNode;

  // assign this new node's next as current head of LL
  newNode->next = *head;
}

void display (struct Node *head)
{
  // if there are no node in LL
  if (head == NULL)
    return;

  struct Node *temp = head;

  //need to take care of circular structure of LL
  do
    {
      printf ("%d ", temp->data);
      temp = temp->next;

    }
  while (temp != head);
  printf ("\n");
}

int main ()
{

  struct Node *head = NULL;

  printf("Linked List: ");
  insertLast (&head, 0);
  insertLast (&head, 10);
  insertLast (&head, 20);
  insertLast (&head, 30);
  insertLast (&head, 40);
  display (head);

  return 0;
}

Output

Linked List: 0 10 20 30 40 

Prime Course Trailer

Related Banners

Get PrepInsta Prime & get Access to all 200+ courses offered by PrepInsta in One Subscription

Deletion Operation in Circular Linked List in C

Here is the complete C program that implements deletion operations in a Circular Linked List, including:

  • Delete from Beginning
  • Delete from End
  • Delete a Specific Node

C Program: Delete from Beginning

Code:

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}

void insertEnd(struct Node** head, int value) {
struct Node* newNode = createNode(value);
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;
}
}

void deleteBeginning(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = *head;

// Only one node
if (temp->next == *head) {
free(temp);
*head = NULL;
return;
}

struct Node* last = *head;
while (last->next != *head)
last = last->next;

last->next = temp->next;
*head = temp->next;
free(temp);
}

void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(head)\n");
}

int main() {
struct Node* head = NULL;
insertEnd(&head, 10);
insertEnd(&head, 20);
insertEnd(&head, 30);

printf("Before Deletion (Beginning):\n");
display(head);

deleteBeginning(&head);

printf("\nAfter Deletion from Beginning:\n");
display(head);
return 0;
}

Output:

Before Deletion (Beginning):
10 -> 20 -> 30 -> (head)

After Deletion from Beginning:
20 -> 30 -> (head)

C Program: Delete from End

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}

void insertEnd(struct Node** head, int value) {
struct Node* newNode = createNode(value);
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;
}
}

void deleteEnd(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* curr = *head;

// Only one node
if (curr->next == *head) {
free(curr);
*head = NULL;
return;
}

struct Node* prev = NULL;
while (curr->next != *head) {
prev = curr;
curr = curr->next;
}

prev->next = *head;
free(curr);
}

void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(head)\n");
}

int main() {
struct Node* head = NULL;
insertEnd(&head, 11);
insertEnd(&head, 22);
insertEnd(&head, 33);

printf("Before Deletion (End):\n");
display(head);

deleteEnd(&head);

printf("\nAfter Deletion from End:\n");
display(head);
return 0;
}

Output:

Before Deletion (End):
11 -> 22 -> 33 -> (head)

After Deletion from End:
11 -> 22 -> (head)

C Program: Delete Specific Node

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}

void insertEnd(struct Node** head, int value) {
struct Node* newNode = createNode(value);
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;
}
}

void deleteSpecific(struct Node** head, int key) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}

struct Node *curr = *head, *prev = NULL;

if (curr->data == key) {
// Only one node
if (curr->next == *head) {
free(curr);
*head = NULL;
return;
}

struct Node* last = *head;
while (last->next != *head)
last = last->next;

last->next = curr->next;
*head = curr->next;
free(curr);
return;
}

do {
prev = curr;
curr = curr->next;
} while (curr != *head && curr->data != key);

if (curr->data == key) {
prev->next = curr->next;
free(curr);
} else {
printf("Node with value %d not found.\n", key);
}
}

void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(head)\n");
}

int main() {
struct Node* head = NULL;
insertEnd(&head, 100);
insertEnd(&head, 200);
insertEnd(&head, 300);
insertEnd(&head, 400);

printf("Before Deleting Specific Node:\n");
display(head);

deleteSpecific(&head, 300);

printf("\nAfter Deleting Node with Value 300:\n");
display(head);
return 0;
}

Output:

Before Deleting Specific Node:
100 -> 200 -> 300 -> 400 -> (head)

After Deleting Node with Value 300:
100 -> 200 -> 400 -> (head)

Get over 200+ course One Subscription

Courses like AI/ML, Cloud Computing, Ethical Hacking, C, C++, Java, Python, DSA (All Languages), Competitive Coding (All Languages), TCS, Infosys, Wipro, Amazon, DBMS, SQL and others

Checkout list of all the video courses in PrepInsta Prime Subscription

Checkout list of all the video courses in PrepInsta Prime Subscription

Circular Linked List

  • Introduction to Circular Linked List
    Click Here
  • Circular Linked List Applications
    Click Here
  • Circular Linked List in –
    C | C++ | Java
  • Insertion in Circular Linked List –
    C | C++ | Java
  • Insertion at the beginning–
    C | C++ | Java
  • Insertion at the end –
    C | C++ | Java
  • Insertion at nth position –
    C | C++ | Java
  • Deletion in Circular Linked List –
    C | C++ | Java
  • Deletion from beginning in Circular Linked List –
    C | C++ | Java
  • Deletion from nth position in Circular Linked List –
  • Deletion from end in Circular Linked List –
    C | C++ | Java
  • Insertion and Deletion in Circular Linked List – C | C++ | Java
  • Split a Circular Linked List in two halves –
    C | C++ | Java
  • Count nodes in Circular Linked List –
    C | C++ | Java
  • Sorted Insert In Circular Linked List –
    C | C++ | Java
  • Insertion in the middle in Circular Linked List –
    C | C++ | Java

Circular Linked List