Linked Lists in C — Linear, Circular, Singly, and Doubly
Linked Lists in C — Linear, Circular, Singly, and Doubly
Linked lists are one of the most important and flexible data structures in computer science. Unlike arrays, linked lists allow dynamic memory usage, flexible insertion and deletion, and the ability to grow or shrink as needed. In this blog, we will explore:
- What is a linked list?
- Singly vs Doubly Linked Lists
- Linear vs Circular Structures
- Code examples in C
- Where they're used in real life
What Is a Linked List?
A linked list is a collection of nodes where each node contains:
data
: the valuepointer
: address of the next (and/or previous) node
Unlike arrays, linked lists do not store elements in contiguous memory, which allows dynamic memory allocation and more flexible data structures.
Singly Linked List
In a singly linked list, each node points to the next node in the sequence. The last node points to NULL
.
struct Node {
int data;
struct Node* next;
};
Basic Singly Linked List Operations
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
// Insert at beginning
void insertAtHead(struct Node** head, int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = *head;
*head = newNode;
}
// Print list
void printList(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
insertAtHead(&head, 10);
insertAtHead(&head, 20);
insertAtHead(&head, 30);
printList(head);
return 0;
}
Output:
30 -> 20 -> 10 -> NULL
Doubly Linked List
Each node has two pointers — one to the next node and one to the previous. This allows backward traversal as well.
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
Example in C:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
void insertAtHead(struct Node** head, int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->prev = NULL;
newNode->next = *head;
if (*head != NULL)
(*head)->prev = newNode;
*head = newNode;
}
void printList(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
insertAtHead(&head, 5);
insertAtHead(&head, 15);
insertAtHead(&head, 25);
printList(head);
return 0;
}
Output:
25 <-> 15 <-> 5 <-> NULL
Circular Linked List
In circular linked lists, the last node points back to the head, forming a ring-like structure. It can be singly or doubly circular.
Example (Singly Circular List):
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void insert(struct Node** head, int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = 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 print(struct Node* head) {
if (head == NULL) return;
struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(back to head)\n");
}
int main() {
struct Node* head = NULL;
insert(&head, 100);
insert(&head, 200);
insert(&head, 300);
print(head);
return 0;
}
Output:
100 -> 200 -> 300 -> (back to head)
When to Use What?
- Singly Linked List: Fast forward traversal, simple
- Doubly Linked List: Bidirectional traversal
- Circular List: Perfect for circular buffer structures
Real-Life Applications
- Music playlist rotation (circular linked list)
- Undo/redo functionality (doubly linked list)
- Dynamic memory allocation (linked blocks)
- Job scheduling in OS (circular queue)
Conclusion
Linked lists are dynamic, flexible, and form the backbone of many real-world systems. Understanding them unlocks your ability to build more advanced data structures and improve memory-efficient programs. Learn the variations — singly, doubly, circular — and you’ll be on your way to mastering pointers and low-level thinking in C.
Comments
Post a Comment