Queue using Linked List
Why a linked-list queue?
A queue follows FIFO — First In, First Out. You can build one with an array (see queue in C), but a simple array queue has two weaknesses: a fixed size, and wasted slots after several dequeues. A linked-list queue fixes both by allocating a node for each item and freeing it when removed.
If linked lists are new, read linked list in C first — this lesson builds directly on nodes.
front and rear pointers
We track the queue with two pointers into the node chain:
| Pointer | Points to |
|---|---|
front | The first node — next to be removed |
rear | The last node — where we add |
Both start as NULL for an empty queue.
Enqueue at the rear
Create a node, attach it after rear, and move rear forward.
void enqueue(int x) {
struct Node *n = malloc(sizeof(struct Node));
n->data = x; n->next = NULL;
if (rear == NULL) { front = rear = n; return; } // empty
rear->next = n; // link after current rear
rear = n; // new rear
}Dequeue at the front
Take the front node, advance front, and free the old node.
int dequeue() {
if (front == NULL) { printf("Queue empty\n"); return -1; }
struct Node *temp = front;
int x = temp->data;
front = front->next;
if (front == NULL) rear = NULL; // was the last node!
free(temp);
return x;
}When you dequeue the final node, front becomes NULL. You must also reset rear to NULL, or it will dangle at freed memory.
The complete program
#include <stdio.h>
#include <stdlib.h>
struct Node { int data; struct Node *next; };
struct Node *front = NULL, *rear = NULL;
void enqueue(int x) {
struct Node *n = malloc(sizeof(struct Node));
n->data = x; n->next = NULL;
if (rear == NULL) { front = rear = n; return; }
rear->next = n; rear = n;
}
int dequeue() {
if (front == NULL) { printf("Empty\n"); return -1; }
struct Node *temp = front;
int x = temp->data;
front = front->next;
if (front == NULL) rear = NULL;
free(temp);
return x;
}
int main() {
enqueue(10); enqueue(20); enqueue(30);
printf("Removed: %d\n", dequeue()); // 10
printf("Removed: %d\n", dequeue()); // 20
return 0;
}Removed: 10
Removed: 20
Dry run
| Action | front | rear | Queue |
|---|---|---|---|
| enqueue 10 | 10 | 10 | 10 |
| enqueue 20 | 10 | 20 | 10, 20 |
| enqueue 30 | 10 | 30 | 10, 20, 30 |
| dequeue → 10 | 20 | 30 | 20, 30 |
Common mistakes
- Forgetting to set
rear = NULLwhen the last node is dequeued. - Not handling the empty case in enqueue (both pointers start NULL).
- Forgetting to
freethe dequeued node, causing a memory leak. - Adding at the front or removing at the rear — that breaks FIFO order.
Add a display() function that walks from front to the end printing each value, and call it after every operation to watch the queue change.
Summary
- A linked-list queue uses
frontandrearnode pointers. - Enqueue adds a node at the rear; dequeue removes from the front.
- It grows and shrinks at run time — no fixed size, no wasted slots.
- Reset
reartoNULLwhen the last node leaves. - Always
freethe removed node to avoid leaks.
Frequently Asked Questions
How do you implement a queue using a linked list in C?
front and rear. To enqueue, you create a new node and attach it after rear, then move rear to it. To dequeue, you take the node at front, move front to the next node, and free the old one. This gives a queue that grows and shrinks at run time.Why use a linked list instead of an array for a queue?
What do front and rear point to in a linked-list queue?
front points to the first node — the next item to be removed — and rear points to the last node, where new items are added. When the queue is empty, both are NULL.What happens when you dequeue the last element?
front becomes NULL. You must also set rear to NULL, otherwise rear would point to freed memory and the next enqueue would misbehave. Handling this case is a common source of bugs.