Yes. Ignore the pseudocode for a moment. The main thing you need to understand is what a queue is. Once that clicks, both Question 2 and Question 3 are basically the same operation stored in two different ways.
0. What even is a queue?
Think of an actual queue at a food stall:
FRONT REAR
↓ ↓
[Alice] → [Bob] → [Charlie] → [David]
leaves joins
here here
A queue follows:
FIFO = First In, First Out
Alice joined first, so Alice leaves first.
There are only 2 operations you need to know:
| Operation | Meaning | Where? |
|---|---|---|
| Enqueue | Add an item | REAR |
| Dequeue | Remove an item | FRONT |
So memorise:
ENQUEUE → REAR
DEQUEUE → FRONT
Question 2 — Queue using an ARRAY
The question says:
A queue is held in an array
q[1]toq[n].
Suppose n = 5.
Initially:
Array position:
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┘
COUNT = 0
Now enqueue "A":
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ A │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┘
↑
FRONT
↑
REAR
Enqueue "B":
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ A │ B │ │ │ │
└─────┴─────┴─────┴─────┴─────┘
↑ ↑
FRONT REAR
Enqueue "C":
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ A │ B │ C │ │ │
└─────┴─────┴─────┴─────┴─────┘
↑ ↑
FRONT REAR
Now dequeue.
Remember:
dequeue removes from the FRONT
So "A" comes out.
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ │ B │ C │ │ │
└─────┴─────┴─────┴─────┴─────┘
↑ ↑
FRONT REAR
Notice something important:
We do NOT need to move B and C.
We simply move the FRONT pointer.
But there is a problem
Suppose we continue.
After using the queue for a while:
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ │ │ C │ D │ E │
└─────┴─────┴─────┴─────┴─────┘
↑ ↑
FRONT REAR
There are empty spaces at positions 1 and 2.
But REAR is already at position 5.
Should we say:
“Oops, queue is full”?
No! There are two empty spaces.
So we make the array behave like a circle.
Circular queue
Imagine:
1 → 2 → 3 → 4 → 5
↑ ↓
└─────────────────┘
After position 5, we go back to position 1.
So if REAR = 5 and another item is added:
REAR becomes 1
For example:
1 2 3 4 5
┌─────┬─────┬─────┬─────┬─────┐
q │ F │ │ C │ D │ E │
└─────┴─────┴─────┴─────┴─────┘
↑ ↑
REAR FRONT
The logical queue is:
C → D → E → F
Even though physically it looks weird in the array.
This is a circular queue.
What variables do we need?
Use three pieces of information:
FRONT = position of first item
REAR = position of last item
COUNT = number of items currently in queue
COUNT is especially useful because:
COUNT = 0 → queue EMPTY
COUNT = n → queue FULL
This directly deals with the errors mentioned in the question.
Question 2(a): Adding an item
Before worrying about pseudocode, think in English.
When adding an item:
1. Check whether queue is full.
2. If full → error.
3. Otherwise move REAR to next position.
4. If REAR goes beyond n, wrap around to 1.
5. Put the new item there.
6. Increase COUNT.
That’s the entire algorithm.
Pseudocode
Suppose initially:
FRONT ← 1
REAR ← 0
COUNT ← 0
Then enqueue:
IF COUNT = n THEN
OUTPUT "Queue is full"
ELSE
REAR ← REAR + 1
IF REAR > n THEN
REAR ← 1
ENDIF
q[REAR] ← item
COUNT ← COUNT + 1
ENDIF
Don’t memorise those lines individually yet.
Understand the shape:
check full
↓
move rear
↓
wrap around if necessary
↓
insert item
↓
count + 1
Question 2(b): Removing an item
Again, first do it in English.
1. Check whether queue is empty.
2. If empty → error.
3. Otherwise take the item at FRONT.
4. Move FRONT forward.
5. If FRONT goes beyond n, wrap back to 1.
6. Decrease COUNT.
Pseudocode:
IF COUNT = 0 THEN
OUTPUT "Queue is empty"
ELSE
item ← q[FRONT]
FRONT ← FRONT + 1
IF FRONT > n THEN
FRONT ← 1
ENDIF
COUNT ← COUNT - 1
ENDIF
The pattern you should notice
Compare the two:
ADD
check FULL
move REAR
add item
COUNT + 1
REMOVE
check EMPTY
take FRONT item
move FRONT
COUNT - 1
That is much easier to memorise.
Question 3 — Queue using a LINKED LIST
Now we change how the queue is stored.
The queue itself has not changed.
It is still:
enqueue → rear
dequeue → front
The only difference is that instead of an array:
q[1] q[2] q[3] q[4] ...
we use nodes.
What is a linked-list node?
Each node contains two things:
┌──────────┬──────────┐
│ DATA │ NEXT │
└──────────┴──────────┘
For example:
┌─────┬─────┐ ┌─────┬─────┐ ┌─────┬──────┐
│ A │ •──┼────→│ B │ •──┼────→│ C │ NULL │
└─────┴─────┘ └─────┴─────┘ └─────┴──────┘
NEXT tells you where the next node is.
Question 3(a)
Draw a diagram to show how a queue can be implemented using a linked list.
We simply add two pointers:
FRONTREAR
FRONT REAR
│ │
↓ ↓
┌─────┬─────┐ ┌─────┬─────┐ ┌─────┬──────┐
│ A │ •──┼────→│ B │ •──┼────→│ C │ NULL │
└─────┴─────┘ └─────┴─────┘ └─────┴──────┘
The queue is:
A → B → C
Who leaves next?
A, because A is at FRONT.
Where will D be added?
After C, because C is the REAR.
Why do we keep both FRONT and REAR?
Because we need to do this:
REMOVE ADD
↓ ↓
FRONT REAR
↓ ↓
[A] → [B] → [C] → [D]
So:
Front tells us where to delete.
Rear tells us where to insert.
This is basically the entire idea behind Question 3.
Question 3(b)(i): Add an item
Let’s say we currently have:
FRONT REAR
↓ ↓
[A] ─────→ [B] ─────→ [C] ─────→ NULL
We want to enqueue D.
First create:
[D] → NULL
Then make C point to D:
[A] → [B] → [C] → [D] → NULL
Finally move REAR:
FRONT REAR
↓ ↓
[A] ─────→ [B] ─────→ [C] ─────→ [D] → NULL
So conceptually:
1. Create new node.
2. Put item inside it.
3. Its NEXT is NULL.
4. Make current REAR point to it.
5. Move REAR to new node.
There is one special case: empty queue
Suppose the queue starts empty:
FRONT → NULL
REAR → NULL
Then you enqueue A.
There’s no existing rear node that can point at A.
So both pointers simply become A:
FRONT
↓
[A] → NULL
↑
REAR
This gives us the algorithm:
Create NEWNODE
NEWNODE.DATA ← item
NEWNODE.NEXT ← NULL
IF FRONT = NULL THEN
FRONT ← NEWNODE
REAR ← NEWNODE
ELSE
REAR.NEXT ← NEWNODE
REAR ← NEWNODE
ENDIF
Don’t memorise it as random commands.
Think:
NEW NODE
↓
Is queue empty?
↓
YES NO
↓ ↓
front = new old rear → new
rear = new rear = new
Question 3(b)(ii): Remove an item
Suppose:
FRONT REAR
↓ ↓
[A] ─────→ [B] ─────→ [C] ─────→ NULL
We dequeue.
Who gets removed?
A.
So first get its value:
item = A
Then move FRONT to the next node.
Before:
FRONT
↓
[A] → [B] → [C]
After:
FRONT
↓
[A] [B] → [C]
Then delete A:
FRONT REAR
↓ ↓
[B] ─────→ [C] ─────→ NULL
So conceptually:
1. Check whether queue is empty.
2. Take item from FRONT.
3. Move FRONT to FRONT's next node.
4. Delete old front.
Pseudocode:
IF FRONT = NULL THEN
OUTPUT "Queue is empty"
ELSE
TEMP ← FRONT
item ← FRONT.DATA
FRONT ← FRONT.NEXT
DELETE TEMP
ENDIF
One final special case
Imagine there is only one node:
FRONT
↓
[A] → NULL
↑
REAR
Remove A.
Now:
FRONT → NULL
But REAR must also become NULL.
Otherwise REAR would still point to an item that doesn’t exist.
So the complete algorithm is:
IF FRONT = NULL THEN
OUTPUT "Queue is empty"
ELSE
TEMP ← FRONT
item ← FRONT.DATA
FRONT ← FRONT.NEXT
IF FRONT = NULL THEN
REAR ← NULL
ENDIF
DELETE TEMP
ENDIF
The BIG picture — compare Q2 and Q3
This is what I want you to internalise rather than memorising two completely separate topics.
| Array Queue | Linked-list Queue | |
|---|---|---|
| Add | at REAR | at REAR |
| Remove | from FRONT | from FRONT |
| Full? | COUNT = n | Usually only if memory runs out |
| Empty? | COUNT = 0 | FRONT = NULL |
| Enqueue | move rear + insert | attach new node to rear |
| Dequeue | take front + move front | delete front node |
So the queue logic never changes.
Only the storage changes.
The two exam techniques to memorise
If tomorrow I gave you a blank sheet and asked both questions, start by writing:
QUEUE = FIFO
ADD → REAR
REMOVE → FRONT
Then:
If it’s an ARRAY
ENQUEUE:
check FULL
→ move REAR
→ insert
→ count + 1
DEQUEUE:
check EMPTY
→ take FRONT
→ move FRONT
→ count - 1
If it’s a LINKED LIST
ENQUEUE = INSERT AT TAIL
DEQUEUE = DELETE AT HEAD
That last line is especially useful because you’ve already seen linked lists:
Queue implemented with linked list = insert at tail + delete at head.
If you understand that sentence, you understand about 80–90% of Question 3.