First exams 2027 · SL & HL

B2.2.3 · Data structures

Stacks: last in, first out

Some collections don't care about order at all. A stack cares about exactly one thing: whatever went in most recently is the only thing you can ever take out next.

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

Explainer

A stack of trays at a cafeteria counter works one way and one way only: a clean tray goes on TOP of the pile, and whoever takes the next tray takes the one sitting on top, never one from partway down the pile. It's physically impossible to pull a tray out of the middle without disturbing everything above it. A program can enforce that exact same restriction on purpose, and that restriction is the entire point of the structure.

Df

A stack is an abstract data structure that works on the Last In, First Out (LIFO) principle, sometimes called First In, Last Out (FILO). Only the item most recently added, the item on top, can be accessed, added to, or removed. Everything below it is temporarily unreachable.

Static or dynamic underneath, either way

A stack can be built two ways: as a static structure using an array (a fixed maximum size, decided upfront), or as a dynamic structure with its elements chained together via references, no fixed limit, growing one item at a time. The LIFO behaviour is identical either way, this is the same static-vs-dynamic choice from B2.2.1, just applied to one specific structure. (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. Each does exactly one job, and no two of them do the same job.

OperationWhat it doesPython (a function per operation)Java (java.util.Stack)
pushAdd a new item to the toppush(stack, value)stack.push(value);
popRemove AND return the top itempop(stack)stack.pop();
peekReturn the top item WITHOUT removing itpeek(stack)stack.peek();
isEmptyCheck whether the stack has anything in it at allis_empty(stack)stack.isEmpty();

Java's own Stack class happens to name its methods identically to the syllabus terms, push/pop/peek/isEmpty, so there's no vocabulary gap to bridge on this statement, unlike some others.

Py

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

def push(stack, item): stack.append(item) def pop(stack): return stack.pop() def peek(stack): return stack[-1] def is_empty(stack): return len(stack) == 0

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

!

peek and pop are not the same operation, and mixing them up is the single most common slip on this statement. peek only looks, the stack is completely unchanged afterward. pop genuinely removes the top item, the stack is one item smaller afterward. If a question needs the stack unchanged for a later step, that's peek, never pop.

!

Overflow and underflow are the two failure conditions named alongside these operations. Stack overflow is attempting to push onto a stack that's already at its maximum size (only possible for a static, array-based stack with a genuine fixed limit). Stack underflow is attempting to pop (or peek) from a stack that's already empty, there's nothing there to return. A static implementation commonly adds a fifth operation, isFull, checked BEFORE every push specifically to catch overflow before it happens rather than after.

Explainer

How the choice of implementation affects performance and memory

This is the statement's second named requirement, and it's a direct application of B2.2.1's comparison to one specific structure.

Array-based stack (static)

Real example: a fixed-size stack of at most 20 trays, the counter genuinely cannot hold a 21st.

Advantage

  • Fast push/pop (writing to or reading from one known index, no memory allocation needed on every operation)

Disadvantage

  • A genuine maximum size (push past that size is a real stack overflow, not just a slow operation)
Chained/dynamic stack

Real example: an undo history with no sensible upper limit on how many actions a user might take.

Advantage

  • No fixed limit (genuinely cannot overflow, it 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 push)

Worked example

An undo history for a drawing app

Every action a user takes gets pushed onto a stack. Undo pops the most recent one, whatever that happens to be, which is exactly the behaviour LIFO guarantees and a queue never could.

push, peek, pop and isEmpty on a real undo history Step 1 of 5

Step 1. Three actions, pushed in order. Each call to push adds to the top. The stack now holds, top to bottom, the reverse of the order they happened in.

history = [] push(history, "draw circle") push(history, "draw square") push(history, "draw line")
history (top first)
draw lineTOP
draw square
draw circle

Step 2. peek before deciding anything. The app checks what undo WOULD affect, without changing the stack at all.

print("Undo would remove:", peek(history))
history (unchanged)
draw lineTOP
draw square
draw circle

Step 3. pop actually undoes it. "draw line" is removed and returned. The stack is genuinely one item smaller now, "draw square" is the new top.

undone = pop(history) print("Undid:", undone)
history
draw squareTOP
draw circle

Step 4. isEmpty guards every undo request. Before popping again, the app must check there's actually something to undo.

if is_empty(history): print("Nothing left to undo") else: print("Undid:", pop(history))
history
draw circleTOP

Step 5. One more undo, then genuinely empty. The isEmpty check is what stops the NEXT undo from underflowing, attempting to pop again here would be exactly the failure case named above.

if is_empty(history): print("Nothing left to undo") else: print("Undid:", pop(history))
history
empty, isEmpty() is now True

Try it yourself

Run the undo history

The same push/peek/pop/isEmpty sequence as the steps above, live and editable, using the same four functions. An experiment is waiting at the bottom: keep undoing past the point where the stack is empty, and watch pop's stack.pop() raise a real error instead of quietly doing nothing.

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 stacks (append, pop, negative indexing, len), exactly what this page needs, but it isn't full Python.

Check your understanding

A stack holds, top to bottom: "C", "B", "A". peek() is called, then pop() is called. What does the stack 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 stack, a vague answer like "stacks are used for undo" is reported as not specific enough to earn the mark. The mark is for describing an actual mechanism, not just naming a use case in passing.

The second common slip is confusing peek with pop, treating "look at the top" and "remove the top" as interchangeable when a question depends on the stack being unchanged afterward.

Answer frame that scores: name the application AND explain the specific push/pop mapping. "An undo feature" is not enough; "each action a user takes is pushed onto a stack, and using undo pops the most recent action back off" is.

✕

What the vague version looks like: "A stack could be used to undo actions in an app." Names a use case, explains nothing about how push/pop actually implement it.

✓

What it should say: "Each action the user takes is pushed onto a stack as it happens. When undo is triggered, the stack is popped, removing and reversing the most recently performed action, exactly the LIFO order undoing requires." States the mechanism, not just the label.

Revision questions

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

Question 1 · 2 marks

[2]Distinguish between the peek and pop operations on a stack.

Question 2 · 3 marks

[3]Explain how a stack could be used to implement the "back" button in a web browser.

Question 3 · 4 marks

[4]Compare an array-based (static) stack with a chained, dynamic stack in terms of performance and memory usage.

Flashcards

Active recall for this statement’s key terms.