🚶 Queue
Learn the FIFO principle, understand enqueue/dequeue/front/rear operations, visualize a linear array queue, and trace the exact C program step by step.
📖 Queue Overview
A queue is a linear data structure in which insertion happens at one end, called the rear, and deletion happens at the other end, called the front.
💡 FIFO Principle
Queue follows First In, First Out (FIFO). The element inserted first is the first element removed.
🧠 Real-Life Example
Think about people standing in a ticket queue. The person who joins first is normally served first. New people join at the rear, while service happens from the front.
⚙️ Queue Operations
front and rear move only forward.
Therefore, after rear == MAX - 1, no new element can be inserted even if earlier
array positions became free after dequeues. Circular Queue solves this limitation.
🧱 Queue Using Array
A linear array queue uses two integer variables:
front identifies the first valid element and
rear identifies the last valid element.
#define MAX 5
int queue[MAX];
int front = -1;
int rear = -1;
Empty Queue
Initially, front = -1 and rear = -1.
When the first element is enqueued, front becomes 0.
➕ Enqueue Operation
ENQUEUE(value)
1. If rear == MAX - 1
Queue Overflow
2. If front == -1
front = 0
3. rear = rear + 1
4. queue[rear] = value
Example
If the queue contains 10, 20, 30 with
front = 0 and rear = 2,
then Enqueue(40) makes rear = 3 and stores 40 at queue[3].
➖ Dequeue Operation
DEQUEUE()
1. If front == -1
Queue Underflow
2. value = queue[front]
3. If front == rear
front = rear = -1
Else
front = front + 1
4. Return value
Example
For 10, 20, 30, Dequeue removes 10.
After the operation, front moves from index 0 to index 1.
👀 Front and Rear Operations
Front returns queue[front] and
Rear returns queue[rear].
Neither operation removes an element.
FRONT()
if front == -1
Queue is empty
else
return queue[front]
REAR()
if rear == -1
Queue is empty
else
return queue[rear]
💻 Linear Array Queue Program in C
Visible Learning Program
#include <stdio.h>
#define MAX 5
int queue[MAX];
int front = -1;
int rear = -1;
void enqueue(int value)
{
if(rear == MAX - 1)
{
printf("Queue Overflow\n");
return;
}
if(front == -1)
front = 0;
rear++;
queue[rear] = value;
}
int dequeue()
{
int value;
if(front == -1)
return -1;
value = queue[front];
if(front == rear)
{
front = -1;
rear = -1;
}
else
{
front++;
}
return value;
}
int peekFront()
{
if(front == -1)
return -1;
return queue[front];
}
int peekRear()
{
if(rear == -1)
return -1;
return queue[rear];
}
int main()
{
enqueue(10);
enqueue(20);
enqueue(30);
printf("Dequeued: %d\n", dequeue());
enqueue(40);
printf("Front: %d\n", peekFront());
printf("Rear: %d\n", peekRear());
return 0;
}
Program Output
Dequeued: 10
Front: 20
Rear: 40
Final Queue
20 30 40
front = 1
rear = 3
💻 Program
🧠 What is happening?
📊 Live Variables
🧱 Live Queue Array
—
⚡ Linear Queue Complexity
O(n).
Use a Circular Queue to reuse freed positions while keeping operations O(1).
🔄 Circular Queue
A circular queue treats the last array position as connected back to the first. This lets REAR reuse positions that became free after dequeue operations.
💡 Why Circular Queue?
A linear array queue can waste positions before FRONT. Circular Queue reuses those positions without shifting elements, so the fixed array is used more efficiently.
rear = (rear + 1) % MAX
front = (front + 1) % MAX
(rear + 1) % MAX == front
🧠 Wrap-Around Example
For capacity 5, if rear = 4 and index 0 is free,
the next REAR becomes (4 + 1) % 5 = 0.
That is the key circular movement.
| Feature | Linear Queue | Circular Queue |
|---|---|---|
| Reuse freed positions | No | Yes |
| REAR movement | Only forward | Wraps using modulo |
| False overflow | Possible | Avoided |
| Enqueue / Dequeue | O(1) | O(1) |
⚙️ Circular Queue Operations
Enqueue Algorithm
CIRCULAR_ENQUEUE(value)
1. If (rear + 1) % MAX == front
Queue Overflow
2. If front == -1
front = 0
3. rear = (rear + 1) % MAX
4. queue[rear] = value
Dequeue Algorithm
CIRCULAR_DEQUEUE()
1. If front == -1
Queue Underflow
2. value = queue[front]
3. If front == rear
front = rear = -1
Else
front = (front + 1) % MAX
4. Return value
MAX = 5, modulo creates this index movement:
0 → 1 → 2 → 3 → 4 → 0 → 1 ....
💻 Circular Queue Program in C
Visible Learning Program
#include <stdio.h>
#define MAX 5
int queue[MAX];
int front = -1;
int rear = -1;
int isFull()
{
return (rear + 1) % MAX == front;
}
void enqueue(int value)
{
if(isFull())
{
printf("Queue Overflow\n");
return;
}
if(front == -1)
front = 0;
rear = (rear + 1) % MAX;
queue[rear] = value;
}
int dequeue()
{
int value;
if(front == -1)
return -1;
value = queue[front];
if(front == rear)
{
front = -1;
rear = -1;
}
else
{
front = (front + 1) % MAX;
}
return value;
}
int peekFront()
{
if(front == -1)
return -1;
return queue[front];
}
int peekRear()
{
if(rear == -1)
return -1;
return queue[rear];
}
int main()
{
enqueue(10);
enqueue(20);
enqueue(30);
enqueue(40);
printf("Dequeued: %d\n", dequeue());
printf("Dequeued: %d\n", dequeue());
enqueue(50);
enqueue(60);
printf("Front: %d\n", peekFront());
printf("Rear: %d\n", peekRear());
return 0;
}
Program Output
Dequeued: 10
Dequeued: 20
Front: 30
Rear: 60
Final Circular Queue
Logical order:
30 40 50 60
front = 2
rear = 0
REAR wrapped to index 0.
💻 Program
🧠 What is happening?
📊 Live Variables
🔄 Live Circular Queue Array
—
⚡ Circular Queue Complexity
(rear + 1) % MAX == front, while the empty condition is
front == -1.
🔗 Queue Using Linked List
A queue can also be implemented with a linked list. Instead of reserving a fixed array, each queue element is stored in a dynamically allocated node.
💡 FRONT and REAR Pointers
FRONT points to the first node, which will be removed next. REAR points to the last node, where the next node will be inserted.
struct Node
{
int data;
struct Node *next;
};
struct Node *front = NULL;
struct Node *rear = NULL;
⚙️ Enqueue and Dequeue Using Linked List
Enqueue
ENQUEUE(value)
1. Create newNode
2. newNode->data = value
3. newNode->next = NULL
4. If rear == NULL
front = rear = newNode
return
5. rear->next = newNode
6. rear = newNode
Dequeue
DEQUEUE()
1. If front == NULL
Queue Underflow
2. temp = front
3. value = temp->data
4. front = front->next
5. If front == NULL
rear = NULL
6. free(temp)
7. return value
🧠 Key Edge Case
When the final node is dequeued, front becomes NULL.
At that moment, rear must also become NULL; otherwise REAR would point to freed memory.
💻 Queue Using Linked List — C Program
Visible Learning Program
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *front = NULL;
struct Node *rear = NULL;
void enqueue(int value)
{
struct Node *newNode =
(struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if(rear == NULL)
{
front = newNode;
rear = newNode;
return;
}
rear->next = newNode;
rear = newNode;
}
int dequeue()
{
struct Node *temp;
int value;
if(front == NULL)
return -1;
temp = front;
value = temp->data;
front = front->next;
if(front == NULL)
rear = NULL;
free(temp);
return value;
}
int peekFront()
{
if(front == NULL)
return -1;
return front->data;
}
int peekRear()
{
if(rear == NULL)
return -1;
return rear->data;
}
int main()
{
enqueue(10);
enqueue(20);
enqueue(30);
printf("Dequeued: %d\n", dequeue());
enqueue(40);
printf("Front: %d\n", peekFront());
printf("Rear: %d\n", peekRear());
return 0;
}
Program Output
Dequeued: 10
Front: 20
Rear: 40
Final Queue
FRONT → 20 → 30 → 40 → NULL
↑
REAR
💻 Program
🧠 What is happening?
📊 Live Variables
🔗 Live Queue Memory
—
⚡ Linked List Queue Complexity
↔️ Deque (Double Ended Queue)
A Deque is a queue in which insertion and deletion are allowed at both ends. The name Deque comes from Double Ended Queue.
💡 Main Idea
A normal queue inserts at REAR and deletes from FRONT. A Deque is more flexible: it can insert and delete at both FRONT and REAR.
⚙️ Deque Algorithms
Insert at Front
INSERT_FRONT(value)
1. If Deque is full
Overflow
2. If Deque is empty
front = rear = 0
3. Else if front == 0
front = MAX - 1
4. Else
front = front - 1
5. deque[front] = value
Insert at Rear
INSERT_REAR(value)
1. If Deque is full
Overflow
2. If Deque is empty
front = rear = 0
3. Else if rear == MAX - 1
rear = 0
4. Else
rear = rear + 1
5. deque[rear] = value
Delete at Front
DELETE_FRONT()
1. If Deque is empty
Underflow
2. value = deque[front]
3. If front == rear
front = rear = -1
4. Else if front == MAX - 1
front = 0
5. Else
front = front + 1
6. Return value
Delete at Rear
DELETE_REAR()
1. If Deque is empty
Underflow
2. value = deque[rear]
3. If front == rear
front = rear = -1
4. Else if rear == 0
rear = MAX - 1
5. Else
rear = rear - 1
6. Return value
💻 Circular Array Deque Program in C
Visible Learning Program
#include <stdio.h>
#define MAX 6
int deque[MAX];
int front = -1;
int rear = -1;
int isEmpty()
{
return front == -1;
}
int isFull()
{
return (front == 0 && rear == MAX - 1) ||
(front == rear + 1);
}
void insertFront(int value)
{
if(isFull())
{
printf("Deque Overflow\n");
return;
}
if(isEmpty())
{
front = 0;
rear = 0;
}
else if(front == 0)
{
front = MAX - 1;
}
else
{
front--;
}
deque[front] = value;
}
void insertRear(int value)
{
if(isFull())
{
printf("Deque Overflow\n");
return;
}
if(isEmpty())
{
front = 0;
rear = 0;
}
else if(rear == MAX - 1)
{
rear = 0;
}
else
{
rear++;
}
deque[rear] = value;
}
int deleteFront()
{
int value;
if(isEmpty())
return -1;
value = deque[front];
if(front == rear)
{
front = -1;
rear = -1;
}
else if(front == MAX - 1)
{
front = 0;
}
else
{
front++;
}
return value;
}
int deleteRear()
{
int value;
if(isEmpty())
return -1;
value = deque[rear];
if(front == rear)
{
front = -1;
rear = -1;
}
else if(rear == 0)
{
rear = MAX - 1;
}
else
{
rear--;
}
return value;
}
int getFront()
{
if(isEmpty())
return -1;
return deque[front];
}
int getRear()
{
if(isEmpty())
return -1;
return deque[rear];
}
int main()
{
insertRear(20);
insertRear(30);
insertFront(10);
insertRear(40);
printf("Deleted Front: %d\n", deleteFront());
printf("Deleted Rear: %d\n", deleteRear());
insertFront(5);
insertRear(50);
printf("Front: %d\n", getFront());
printf("Rear: %d\n", getRear());
return 0;
}
Program Output
Deleted Front: 10
Deleted Rear: 40
Front: 5
Rear: 50
Final Logical Deque
5 20 30 50
front = 5
rear = 2
FRONT wrapped to index 5.
💻 Program
🧠 What is happening?
📊 Live Variables
↔️ Live Deque Array
—
⚡ Deque Complexity
⭐ Priority Queue
A Priority Queue stores elements together with a priority. Removal is based on priority rather than only on insertion order.
💡 Priority Rule Used Here
In this implementation, a larger priority number means higher priority. If two elements have the same priority, the one inserted earlier is removed first.
🧠 Example
For (10,2), (20,5), (30,3), (40,5),
the highest priority is 5. Since 20 was inserted before 40,
20 is removed first.
⚙️ Priority Queue Operations
Enqueue
ENQUEUE(data, priority)
1. If count == MAX
Overflow
2. queue[count].data = data
3. queue[count].priority = priority
4. count = count + 1
Find Highest Priority
HIGHEST_PRIORITY_INDEX()
1. If count == 0
return -1
2. index = 0
3. For i = 1 to count - 1
If queue[i].priority > queue[index].priority
index = i
4. return index
Delete Highest Priority
DEQUEUE_HIGHEST()
1. Find highest-priority index
2. Save its data
3. Shift later items one position left
4. count = count - 1
5. Return removed data
data:priority, for example
10:2,20:5,30:3.
💻 Priority Queue Using Array — C Program
Visible Learning Program
#include <stdio.h>
#define MAX 6
struct Item
{
int data;
int priority;
};
struct Item queue[MAX];
int count = 0;
void enqueue(int data, int priority)
{
if(count == MAX)
{
printf("Priority Queue Overflow\n");
return;
}
queue[count].data = data;
queue[count].priority = priority;
count++;
}
int highestPriorityIndex()
{
int index = 0;
if(count == 0)
return -1;
for(int i = 1; i < count; i++)
{
if(queue[i].priority > queue[index].priority)
index = i;
}
return index;
}
int dequeueHighest()
{
int index;
int value;
if(count == 0)
return -1;
index = highestPriorityIndex();
value = queue[index].data;
for(int i = index; i < count - 1; i++)
queue[i] = queue[i + 1];
count--;
return value;
}
int peekHighest()
{
int index;
if(count == 0)
return -1;
index = highestPriorityIndex();
return queue[index].data;
}
int main()
{
enqueue(10, 2);
enqueue(20, 5);
enqueue(30, 3);
enqueue(40, 5);
printf("Removed: %d\n", dequeueHighest());
printf("Highest: %d\n", peekHighest());
enqueue(50, 6);
printf("Highest: %d\n", peekHighest());
return 0;
}
Program Output
Removed: 20
Highest: 40
Highest: 50
Final Priority Queue
(10,2) (30,3) (40,5) (50,6)
count = 4
highest item = 50
highest priority = 6
💻 Program
🧠 What is happening?
📊 Live Variables
⭐ Live Priority Queue
—
⚡ Priority Queue Complexity
📊 Queue Types — Complete Comparison
The best Queue implementation depends on how elements must be inserted, removed, prioritized, and stored. Use this table as a quick revision before interviews and placements.
| Queue Type | Main Rule | Enqueue / Insert | Delete | Space | Important Advantage | Main Limitation / Note |
|---|---|---|---|---|---|---|
| Linear Array Queue | FIFO | O(1) | O(1) | O(MAX) | Simple implementation | May waste positions before FRONT and cause false overflow |
| Circular Queue | FIFO + wrap-around | O(1) | O(1) | O(MAX) | Reuses freed array positions | Needs careful full/empty conditions |
| Linked Queue | FIFO | O(1) | O(1) | O(n) | Dynamic size; no fixed array capacity | Extra pointer memory and dynamic allocation |
| Deque | Both-end access | O(1) at both ends | O(1) at both ends | O(MAX) or O(n) | Very flexible two-end operations | More pointer/index cases than a normal Queue |
| Priority Queue | Priority-based service | Depends on implementation | Depends on implementation | O(n) | Serves the most important item first | Heap implementation is preferred for efficient updates |
🌍 Real-World Applications of Queue
❓ Common Queue Interview Questions
rear == MAX - 1. Underflow occurs when a dequeue or peek
is attempted while front == -1.
(rear + 1) % MAX == front.
(4 + 1) % 5 = 0.
🎯 20 Queue Practice Problems
Try every problem yourself first. Use 💻 Solve It Yourself to write and test your C program. Open Hint only when necessary, and use Show Program when you want to study the complete solution.
🏆 Scoring
Pass all 5 tests without help for up to 100 points. Opening a hint caps the competitive score at 90. Opening the official program still lets you complete the problem, but it is recorded as Completed rather than competitively solved.