First exams 2027 · SL & HL

B2.2.4 · Data structures

Queues: first in, first out

A stack always serves the newest arrival first. A queue makes the opposite promise: whoever has been waiting longest is served next, no exceptions.

Core for SL & HL Typically 2–5 marks · AO2/AO3 Command term: explain

Explainer

A shared printer in a school computer room prints jobs in exactly the order they were sent. If Ren's essay was sent first, it prints first, even if three other students send jobs a second later. Nobody's job jumps the line, and nobody's job gets stuck behind a job that arrived after it. That ordering guarantee, oldest request served first, is a queue.

Df

A queue keeps items in the exact order they arrived: every new item joins at the rear, and every removal takes whichever item has been waiting at the front the longest. This ordering rule is called First In, First Out (FIFO).

Same static/dynamic choice as every other structure

A queue can be built as a static structure using an array (fixed maximum size), or as a dynamic structure with its elements chained together via references (no fixed limit). Same trade-off as B2.2.1 and B2.2.3's stack, just applied to a structure with two ends instead of one. (HL students meet this chained structure by name, as a linked list, when they reach B4.1.3.)

Explainer

The four required operations

The syllabus names these four explicitly, and a queue needs two pointers to support them: a front pointer showing where the next removal comes from, and a rear pointer showing where the next addition goes.

OperationWhat it doesPython (a function per operation)Java (java.util.Queue)
enqueueAdd a new item at the rearenqueue(queue, value)queue.add(value);
dequeueRemove AND return the item at the frontdequeue(queue)queue.poll();
frontReturn the front item WITHOUT removing itfront(queue)queue.peek();
isEmptyCheck whether the queue has anything in it at allis_empty(queue)queue.isEmpty();

Java's Queue interface doesn't literally use the words "enqueue" or "dequeue", it names the same four operations add(), poll(), peek() and isEmpty(). The syllabus terms describe the CONCEPT; a real Java program reads these method names instead.

Py

In Python, the cleanest way to teach these four operations is one small function per operation, each taking the queue (a plain list) as its argument:

def enqueue(queue, item): queue.append(item) def dequeue(queue): return queue.pop(0) def front(queue): return queue[0] def is_empty(queue): return len(queue) == 0

Every later example on this page calls these four functions instead of writing append/pop(0) directly, so the queue's four required operations stay named exactly as the syllabus states them.

!

front and dequeue are not the same operation, exactly the same distinction as a stack's peek versus pop. front only reports what's at the front, the queue is unchanged. dequeue genuinely removes it, the queue is one item shorter afterward.

!

Overflow and underflow apply to queues the same way they apply to stacks. Overflow is attempting to enqueue onto a queue already at its maximum size (a real limit only for a static, array-based queue). Underflow is attempting to dequeue (or check front) on a queue that's already empty. A static implementation commonly adds a fifth operation, isFull, checked BEFORE every enqueue, exactly the "rear pointer has caught up to front" test the circular queue below uses to detect a genuinely full queue.

Explainer

How the choice of implementation affects performance and memory

A queue has one memory problem a stack never faces: as items are removed from the front of a plain array, the freed slots at the start are wasted unless something reclaims them.

The circular queue solves the wasted-slot problem

A naive array-based queue that always dequeues from index 0 either has to shift every remaining item down one slot (real work, every single dequeue), or simply never reuses the freed space at the front. A circular queue solves this: the rear pointer wraps back around to index 0 once it reaches the end of the array, reusing slots that earlier removals freed. Telling full from empty comes down to comparing the two pointers: they land on the same slot in both cases, so it's genuinely full only right after an addition made them coincide, and genuinely empty only right after a removal did.

Array-based queue (static, circular)

Real example: a print queue capped at 10 waiting jobs, the room's shared printer genuinely cannot track an 11th.

Advantage

  • Fast enqueue/dequeue (writing to or reading from one known index each time, no shifting needed once it's circular)

Disadvantage

  • A genuine maximum size (an 11th job really does trigger overflow, not just a slow enqueue)
Chained/dynamic queue

Real example: a checkout line with no realistic upper bound on how many shoppers might join it.

Advantage

  • No fixed limit (genuinely cannot overflow, grows one linked node at a time as long as memory allows)

Disadvantage

  • Extra memory per item (every node stores a link to the next one, on top of the value itself, and allocating that node costs real time on every enqueue)

A plain Python list used as a queue has this exact wasted-work problem in real life: list.pop(0) genuinely has to shift every remaining element down by one, which costs more the longer the queue gets. That's precisely why a real production queue reaches for a circular buffer, or Python's own collections.deque, rather than a plain list.

Worked example

A shared classroom printer queue

Three print jobs, sent in order. The printer only ever looks at whichever job has been waiting longest, exactly the FIFO promise.

enqueue, front, dequeue and isEmpty on a real print queue Step 1 of 5

Step 1. Three jobs, enqueued in order. Each call to enqueue joins at the rear. Unlike a stack, the queue reads left to right: oldest (front) on the left.

print_queue = [] enqueue(print_queue, "Essay draft") enqueue(print_queue, "Timetable") enqueue(print_queue, "Lab report")
print_queue (front to rear)
FRONTEssay draft
Timetable
REARLab report

Step 2. front checks what's next, unchanged. The printer can report what it's about to print without touching the queue at all.

print("Next to print:", front(print_queue))
print_queue (unchanged)
FRONTEssay draft
Timetable
REARLab report

Step 3. dequeue actually prints it. "Essay draft" is removed and returned. "Timetable" is now the front, it's been waiting second-longest.

job = dequeue(print_queue) print("Printing:", job)
print_queue
FRONTTimetable
REARLab report

Step 4. isEmpty guards every print request. Before printing again, the printer must check there's actually a job waiting.

if is_empty(print_queue): print("Nothing queued") else: print("Printing:", dequeue(print_queue))
print_queue
FRONT / REARLab report

Step 5. One more job printed, then genuinely empty. That isEmpty check is exactly what stops the next print request from underflowing.

if is_empty(print_queue): print("Nothing queued") else: print("Printing:", dequeue(print_queue))
print_queue
empty, isEmpty() is now True

Try it yourself

Run the print queue

The same enqueue/front/dequeue/isEmpty sequence as the steps above, live and editable, using the same four functions. An experiment is waiting at the bottom: keep dequeuing past the point where the queue is empty, and watch dequeue's pop(0) raise a real error.

main.py
Loading Python engine…
Output
Press Run to see the output here.

Running in offline fallback mode. The full Python engine couldn't load (blocked school network, or no internet), so this console switched automatically to a small hand-written engine. It supports lists used as queues (append, pop(0), indexing, len), exactly what this page needs, but it isn't full Python.

Check your understanding

A queue holds, front to rear: "X", "Y", "Z". front() is called, then dequeue() is called. What does the queue hold afterward, and what did each operation return?

Common mistake

A well-known pattern for stack/queue application questions

RecurringWhen asked to state an application of a queue, a vague answer like "queues are used for printing" is reported as not specific enough to earn the mark. The mark is for describing the actual mechanism, not just naming a use case in passing.

The second common slip is confusing front with dequeue, treating "check what's next" and "remove what's next" as interchangeable when a question depends on the queue being unchanged afterward.

Answer frame that scores: name the application AND explain the specific enqueue/dequeue mapping. "A printer queue" is not enough; "each print job is enqueued as it's sent, and the printer dequeues and processes whichever job has been waiting longest" is.

✕

What the vague version looks like: "A queue could be used for a printer." Names a use case, explains nothing about how enqueue/dequeue actually implement it.

✓

What it should say: "Each print job is enqueued at the rear as it's sent to the printer. The printer repeatedly dequeues from the front, so the job that has been waiting longest is always printed next, exactly the FIFO order the task requires." States the mechanism, not just the label.

Linking question

How this connects to the rest of the syllabus

The IB syllabus is deliberately woven together, not a stack of isolated topics. Here's how queues (and their sibling structure, the stack) connect specifically to A2 (networks).

A2

Are data structures like stacks and queues applicable in networking algorithms for packet routing and load balancing? (A router genuinely does this: incoming packets are enqueued as they arrive, and the router dequeues and forwards whichever packet has been waiting longest, the exact FIFO order this page's printer queue uses, just with packets instead of print jobs. A round-robin load balancer works the same way, cycling through a queue of servers rather than always sending new traffic to the same one. A stack shows up less directly here, mainly inside the routing software itself, such as tracking a call stack of function calls while a routing decision is being computed, rather than in the packet-handling structure itself.)

Revision questions

Past-paper style. Write an answer, then reveal the marking points and mark yourself.

Question 1 · 2 marks

[2]Distinguish between the front and dequeue operations on a queue.

Question 2 · 3 marks

[3]Explain how a queue could be used to model customers waiting at a checkout.

Question 3 · 4 marks

[4]Explain why a circular queue is more memory-efficient than a simple array-based queue that never reuses freed slots.

Flashcards

Active recall for this statement’s key terms.