18.1 What is a Queue?
If a stack is a pile of plates, a queue is a line of people at the school canteen. The first person to join the line is the first one served; newcomers join at the back. Nobody pushes in. That single rule — first in, first out (FIFO) — is what makes a queue different from a stack.
A queue keeps two pointers: front (who's next to be served) and rear (where the last person stood). You add at the rear and remove from the front.
| Term | Meaning |
|---|---|
| Queue | An ADT where items are added at one end (rear) and removed from the other (front). FIFO. |
| FIFO | First In, First Out — the first item added is the first removed. |
| Enqueue | Add a new item at the rear of the queue. |
| Dequeue | Remove and return the item from the front. |
| Front | Pointer to the index of the next item to remove. |
| Rear | Pointer to the index of the last item added. |
| Count | Integer tracking how many items are currently stored. |
| Overflow | Trying to enqueue when the queue is full (count == MAX_SIZE). |
| Underflow | Trying to dequeue when the queue is empty (count == 0). |
| Circular | Using MOD to wrap pointers back to 0, reusing freed slots. |
- FIFO — first in, first out
- Add at rear, remove from front
- Use cases: print queue, ticket system, keyboard buffer
What is a Queue?
18.2 Linear vs Circular Queue
Imagine a queue stored in a list of 5 slots. You enqueue A, B, C, D, E (rear reaches index 4), then dequeue A and B (front moves to index 2). Indexes 0 and 1 are now free, but a plain "linear" queue cannot use them: the rear pointer is already at the end. The queue looks full even though two slots are empty. That is wasted space.
- When a pointer would step past the last index, it wraps back to 0.
- We do this with
(pointer + 1) % MAX_SIZE. - If rear is 4 and MAX_SIZE is 5, then
(4 + 1) % 5 = 0— back to the start, into a freed slot.
# Circular wrap with MOD
rear = (rear + 1) % MAX_SIZE # enqueue: wrap rear
front = (front + 1) % MAX_SIZE # dequeue: wrap front
# Example: rear = 4, MAX_SIZE = 5
# (4 + 1) % 5 = 5 % 5 = 0 -> rear wraps to index 0
# Example: front = 7, MAX_SIZE = 8
# (7 + 1) % 8 = 8 % 8 = 0 -> front wraps to index 0- If you keep a
countof items, "empty" iscount == 0and "full" iscount == MAX_SIZE. - This avoids the tricky case where front and rear point to the same slot, which could mean either empty or full without a count.
- Use (rear + 1) % MAX_SIZE
- (4 + 1) % 5 = ?
- Same rule: (front + 1) % MAX_SIZE
Linear vs Circular Queue
18.2B Interactive Simulator
Try the circular queue yourself. Set MAX_SIZE, enter a value, and click Enqueue or Dequeue. Watch the front (cyan) and rear (amber) pointers move and wrap around. Try to trigger overflow and underflow.
Circular Queue
Status: Enqueue or Dequeue to start.
Code
1MAX_SIZE = 5; queue = [None]*MAX_SIZE2if count == MAX_SIZE:3 return False # overflow4 rear = (rear + 1) % MAX_SIZE5 queue[rear] = item; count += 16if count == 0:7 return None # underflow8 item = queue[front]9 front = (front + 1) % MAX_SIZE10 count -= 1; return item18.3 enqueue() — Add at the Rear
enqueue() adds a new item at the rear of the queue. The order is: check full → move rear with MOD → store item → increment count.
MAX_SIZE = 5
queue = [None] * MAX_SIZE
front = 0 # index of the next item to remove
rear = -1 # index of the last item added
count = 0 # how many items are stored
def enqueue(item):
global rear, count
if count == MAX_SIZE: # is the queue full?
print("Queue overflow")
else:
rear = (rear + 1) % MAX_SIZE # move rear, wrap if needed
queue[rear] = item # store the item
count = count + 1 # one more item now- Always use
rear = (rear + 1) % MAX_SIZE— never justrear = rear + 1. - Without MOD, the queue is linear and wastes space.
- Check full: count == MAX_SIZE, return False
- Else: rear = (rear + 1) % MAX_SIZE
- queue[rear] = item, count += 1
- Return True
- Use global rear, count
- Same shape as enqueue — a procedure that prints instead of returning
enqueue() — Add at Rear
18.4 dequeue() — Remove from the Front
dequeue() removes and returns the front item. The order is: check empty → read item → move front with MOD → decrement count → return item.
def dequeue():
global front, count
if count == 0: # is the queue empty?
return None
else:
item = queue[front] # read the front item
front = (front + 1) % MAX_SIZE # move front, wrap if needed
count = count - 1 # one fewer item now
return item # give it back to the caller- Read
item = queue[front]FIRST, thenfront = (front + 1) % MAX_SIZE. - If you move front first, it no longer points at the item.
- Check empty: count == 0, return -1
- Else: read item, move front with MOD, decrement count, return
- Identical to dequeue — only the empty message differs
dequeue() — Remove from Front
18.5 peek(), is_empty(), is_full()
def is_empty():
return count == 0
def is_full():
return count == MAX_SIZE
def peek():
if is_empty():
return None
return queue[front] # front item, not removed
def spaces_left():
return MAX_SIZE - count- With
count, empty iscount == 0and full iscount == MAX_SIZE. - Without count,
front == rearcould mean either — ambiguous and dangerous.
- You are already tracking this with count
- MAX_SIZE - count
peek(), is_empty(), is_full()
18.6 Tracing Enqueue and Dequeue
A trace shows front, rear, and count after each operation. Remember: rear wraps with (rear + 1) % MAX_SIZE.
# MAX_SIZE = 4, start empty (front=0, rear=-1, count=0)
start front=0 rear=-1 count=0
enqueue X front=0 rear=0 count=1
enqueue Y front=0 rear=1 count=2
dequeue front=1 rear=1 count=1 (X out)
enqueue Z front=1 rear=2 count=2- enq P: f=0 r=0 c=1
- enq Q: f=0 r=1 c=2
- enq R: f=0 r=2 c=3
- deq: f=1 r=2 c=2 (P out)
- deq: f=2 r=2 c=1 (Q out)
- enq S: f=2 r=3 c=2
- enq T: f=2 r=0 c=3 (rear wrapped to 0!)
18.7 Full Exam-Style Question
Tarnima runs an online helpdesk. Support tickets must be answered in the order they arrive. She stores up to 6 tickets in a circular queue.
- The queue is stored as a global list
ticketswith global integersfront,rear,countand a constantMAXset to 6. - Write program code to declare and initialise them all (an empty queue).
- MAX = 6
- tickets = [""] * MAX
- front = 0, rear = -1, count = 0
- Write a function
add_ticket(ref)that adds a ticket at the rear. - Returns True if added, False if full.
- Check full: count == MAX, return False
- rear = (rear + 1) % MAX
- tickets[rear] = ref, count += 1
- Return True
- Write a function
answer_next()that removes and returns the front ticket, - or returns "No tickets" if empty.
- Check empty: count == 0, return "No tickets"
- Read ref = tickets[front]
- front = (front + 1) % MAX
- count -= 1, return ref
Key Points Recap
✓ Key Points Summary
18.8 Practice Tasks
Fifteen exam-style queue tasks. Each shows only the question — click Hint for the thought process, or Help for the worked solution.
- For every queue task the marker checks:
- (1) correct overflow/underflow check (count-based)
- (2) correct MOD wrap for both pointers
- (3) correct read-before-move in dequeue, and (4) returning the dequeued value
- The most common mark loss is forgetting MOD (using +1 instead of (pointer+1) % MAX_SIZE).
Question Bank
Answer all questions, then press Submit Quiz to see your score.
Question 1Multiple Choice
What rule does a queue follow?
Question 2True / False
A circular queue uses (pointer + 1) % MAX_SIZE to wrap pointers.
Question 3Multiple Choice
What is the overflow condition?
Question 4Multiple Choice
What is the underflow condition?
Question 5True / False
enqueue adds at the rear, dequeue removes from the front.
Question 6Multiple Choice
How does rear move in enqueue?
Question 7Multiple Choice
In dequeue(), when do you read the item?
Question 8True / False
If rear = 4 and MAX_SIZE = 5, (rear + 1) % MAX_SIZE = 0.
Question 9Multiple Choice
Which is NOT a use case for a queue?
Question 10Multiple Choice
What does spaces_left() return?
Question 11True / False
Using count avoids the ambiguity of front == rear.
Question 12Multiple Choice
What does peek() return?
Answer all 12 questions to enable submission.