C Notes
Complete guide to implementing linked lists in C covering singly linked list, doubly linked list, circular linked list, all operations with code examples and output.
A linked list is a dynamic data structure where elements are stored in nodes, and each node points to the next one. Unlike arrays, linked lists don't require contiguous memory and can grow or shrink during runtime. This makes them ideal when you don't know the size of data in advance or need frequent insertions and deletions.
Why Use Linked Lists Over Arrays?
| Feature | Array | Linked List |
|---|---|---|
| Memory allocation | Contiguous, fixed | Non-contiguous, dynamic |
| Size | Fixed at creation | Grows/shrinks at runtime |
| Insertion at beginning | O(n) – shift all elements | O(1) – change one pointer |
| Deletion at middle | O(n) – shift elements | O(1) – after reaching node |
| Random access | O(1) – direct indexing | O(n) – must traverse |
| Memory overhead | None | Extra pointer per node |
| Cache performance | Excellent | Poor (scattered memory) |
Singly Linked List
Each node contains data and a pointer to the next node. The last node points to NULL.
Node Structure
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
// Create a new node
Node* createNode(int data) {
Node *newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}Complete Singly Linked List Implementation
List: 5 -> 10 -> 15 -> 20 -> 30 -> NULL Count: 5 Search 20: found at position 3 After deleting 15: 5 -> 10 -> 20 -> 30 -> NULL Reversed: 30 -> 20 -> 10 -> 5 -> NULL
Doubly Linked List
Each node has pointers to both the next and previous nodes, allowing traversal in both directions.
#include <stdio.h>
#include <stdlib.h>
typedef struct DNode {
int data;
struct DNode *prev;
struct DNode *next;
} DNode;
DNode* createDNode(int data) {
DNode *node = (DNode*)malloc(sizeof(DNode));
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
void insertFront(DNode **head, int data) {
DNode *newNode = createDNode(data);
newNode->next = *head;
if (*head != NULL)
(*head)->prev = newNode;
*head = newNode;
}
void insertBack(DNode **head, int data) {
DNode *newNode = createDNode(data);
if (*head == NULL) { *head = newNode; return; }
DNode *temp = *head;
while (temp->next != NULL) temp = temp->next;
temp->next = newNode;
newNode->prev = temp;
}
void deleteDNode(DNode **head, int key) {
DNode *temp = *head;
while (temp != NULL && temp->data != key)
temp = temp->next;
if (temp == NULL) return;
if (temp->prev) temp->prev->next = temp->next;
else *head = temp->next;
if (temp->next) temp->next->prev = temp->prev;
free(temp);
}
void displayForward(DNode *head) {
printf("Forward: ");
while (head != NULL) {
printf("%d <-> ", head->data);
if (head->next == NULL) break;
head = head->next;
}
printf("NULL\n");
printf("Backward: ");
while (head != NULL) {
printf("%d <-> ", head->data);
head = head->prev;
}
printf("NULL\n");
}
int main() {
DNode *head = NULL;
insertBack(&head, 10);
insertBack(&head, 20);
insertBack(&head, 30);
insertFront(&head, 5);
displayForward(head);
deleteDNode(&head, 20);
printf("\nAfter deleting 20:\n");
displayForward(head);
return 0;
}Forward: 5 <-> 10 <-> 20 <-> 30 <-> NULL Backward: 30 <-> 20 <-> 10 <-> 5 <-> NULL After deleting 20: Forward: 5 <-> 10 <-> 30 <-> NULL Backward: 30 <-> 10 <-> 5 <-> NULL
Circular Linked List
The last node points back to the first node instead of NULL, forming a circle.
#include <stdio.h>
#include <stdlib.h>
typedef struct CNode {
int data;
struct CNode *next;
} CNode;
void insertCircular(CNode **head, int data) {
CNode *newNode = (CNode*)malloc(sizeof(CNode));
newNode->data = data;
if (*head == NULL) {
*head = newNode;
newNode->next = newNode; // Points to itself
} else {
CNode *temp = *head;
while (temp->next != *head)
temp = temp->next;
temp->next = newNode;
newNode->next = *head;
}
}
void displayCircular(CNode *head) {
if (head == NULL) { printf("Empty\n"); return; }
CNode *temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(back to %d)\n", head->data);
}
int main() {
CNode *head = NULL;
insertCircular(&head, 10);
insertCircular(&head, 20);
insertCircular(&head, 30);
insertCircular(&head, 40);
displayCircular(head);
return 0;
}10 -> 20 -> 30 -> 40 -> (back to 10)
Interview Questions on Linked Lists
Q1: How do you detect a cycle in a linked list? Use Floyd's cycle detection (tortoise and hare): Two pointers, one moving one step and another two steps. If they meet, there's a cycle.
Q2: How to find the middle element in one pass? Use two pointers – slow moves one step, fast moves two steps. When fast reaches the end, slow is at the middle.
Q3: What's the time complexity of inserting at the beginning vs end? Beginning: O(1). End: O(n) for singly linked list, O(1) if you maintain a tail pointer.
Q4: How do you merge two sorted linked lists? Compare head nodes, pick the smaller one, advance that list's pointer, repeat. Use recursion or iteration.
Q5: What's the advantage of doubly linked list over singly linked list? Bi-directional traversal, O(1) deletion when you have the node pointer (no need to find previous), and easier implementation of certain algorithms like LRU cache.
Summary
Linked lists are fundamental data structures that provide dynamic memory allocation and efficient insertions/deletions. Singly linked lists use less memory but only allow forward traversal. Doubly linked lists enable bi-directional movement at the cost of extra memory. Circular linked lists are useful for round-robin scheduling and buffer management. Choose the right variant based on your access patterns and memory constraints.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Linked List in C – Singly, Doubly, and Circular with Implementation.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, data, structures, linked, list, linked list in c – singly, doubly, and circular with implementation
Related C Programming Topics