Abstract Data Types Using OOP

ADT Stack

A stack implemented with classes and objects — a LIFO collection where items go on and come off the same end (the top). Master the top pointer, the push/pop pair, and the full/empty checks here, and you have the pattern that every other linear ADT reuses. Covers the array-based Stack class, push/pop in pseudocode and Python, peek/isEmpty/overflow/underflow, building a stack from a linked list, and applications (reversing, bracket-matching, file tasks).

26.1 Introduction: The Stack ADT

You have stacked plates, books, or roti on a plate before. The plate you put down last is the one you pick up first — you never pull one out from the middle. That single habit is the whole idea of a stack.

In computing, a stack is a collection where every item is added and removed from the same end, called the top. Because the last item in is the first item out, we call this rule LIFO — Last In, First Out. The computer keeps a single number, the top pointer, that always remembers where the top is.

By the end of this page you will be able to describe a stack in exam language, trace push and pop operations on paper, write the algorithms in pseudocode and in Python, and explain how a stack can be built from a linked list. These are the exact skills Paper 4 tests.

TermMeaning
StackA LIFO collection — items go on and come off the same end (the top).
LIFOLast In, First Out. The most recently pushed item is the first to be popped.
PushAdd an item to the top of the stack.
PopRemove and return the item at the top of the stack.
PeekLook at the top item without removing it. Also called "top".
Top pointerAn index that records where the top item sits in the array.
OverflowTrying to push when the stack is already full.
UnderflowTrying to pop when the stack is empty.
isEmptyA check that returns True when there are no items (top pointer is -1).

26.2 How a Stack Works (LIFO)

Why are we doing this?
  • Before you write a single line of code, you must be able to picture the stack changing as items go on and come off.
  • Examiners hand you a diagram and ask you to fill in the stack and the pointer after a list of operations.
  • This is almost guaranteed on Paper 3 and the logic carries straight into Paper 4 code.

Imagine the stack as a vertical pile that grows upwards. The top pointer always points at the most recently added item. When the stack is empty the pointer is set to -1, because there is no item at any index yet.

Tracing push(10), push(20), push(30) then pop() — watch the top pointer

Empty

·
·
·

top = -1

push(10)

10
·
·

top = 0

push(20)

20
10
·

top = 1

push(30)

30
20
10

top = 2

pop() → 30

20
10
·

top = 1

Each push moves the top pointer UP; each pop moves it DOWN. The last value pushed (30) is the first value popped — that is LIFO.

Key rule
  • An empty stack has top = -1.
  • A push does top ← top + 1 then stores the value.
  • A pop reads the value then does top ← top - 1.
  • Order matters — get it backwards and you overwrite or lose data.
Exam tip:
  • When a diagram question says “include the current stack pointer after each group”, a correct stack with a missing or wrong pointer still drops a mark.
  • Always write the pointer value or draw the arrow every single time.

26.3 The Array-Based Stack Class

Why are we doing this?
  • Paper 4 asks you to build the stack, not just describe it.
  • The cleanest exam-ready version uses a fixed-size list plus an integer top pointer — exactly how Cambridge models it in pseudocode with an ARRAY and a TopPointer.
  • Learn this one class and you can answer “write program code for Push/Pop” questions directly.

Here is the complete class. Every method is short; read it once, then read the line-by-line notes below.

class Stack:
    def __init__(self, size=10):
        self.items = [None] * size   # fixed-size storage
        self.maxSize = size          # capacity
        self.top = -1                # empty stack

    def isEmpty(self):
        return self.top == -1

    def isFull(self):
        return self.top == self.maxSize - 1

    def push(self, item):
        if self.isFull():
            return "Stack Overflow"
        self.top += 1                # move pointer up first
        self.items[self.top] = item  # then store the value

    def pop(self):
        if self.isEmpty():
            return "Stack Underflow"
        item = self.items[self.top]  # read value first
        self.items[self.top] = None
        self.top -= 1                # then move pointer down
        return item

    def peek(self):
        if self.isEmpty():
            return "Stack is empty"
        return self.items[self.top]

    def display(self):
        return self.items
Line-by-line explanation
  • __init__ (constructor): self.items = [None] * size creates a fixed list of empty slots. self.maxSize remembers the capacity. self.top = -1 says the stack is empty.
  • isEmpty: Returns True only when the pointer is -1. This is the single source of truth for “empty”.
  • isFull: The last usable index is maxSize - 1 (a list of 10 is indexed 0–9). When top reaches it, the stack is full.
  • push: Check full first to avoid overflow. Move the pointer up, then store — never the other way round.
  • pop: Check empty first. Read the value, blank the slot, move the pointer down, then return the saved value.
  • peek: Returns the top value without changing the pointer.
  • display: Returns the whole list (including None slots) so you can see the internal state while learning.
Exam tip:
  • In Cambridge pseudocode the test is usually written IF TopPointer < MaxSize - 1 for push and IF TopPointer = BasePointer (or = -1) for empty.
  • Match whichever pointer convention the question gives you — some papers start the base at 0, others at -1.

26.4 Push and Pop — Pseudocode & Python

Why are we doing this?
  • Mark scheme: Push and Pop are the two routines Cambridge most often asks you to “complete” or “write program code for” (e.g. 9618/32 O/N 2025 Q12, 9618/22 O/N 2024 Q3).
  • Marks are awarded for the full/empty check, updating the pointer in the right order, and storing/returning the item.
  • Get those three things and you bank the marks.

Push in Cambridge pseudocode:

PROCEDURE Push(NewItem : INTEGER)
    IF TopPointer < MaxSize - 1 THEN
        TopPointer <- TopPointer + 1
        Stack[TopPointer] <- NewItem
    ELSE
        OUTPUT "Stack full"
    ENDIF
ENDPROCEDURE

Pop as a function (returns -1 when empty):

FUNCTION Pop() RETURNS INTEGER
    IF TopPointer = -1 THEN
        RETURN -1            // stack empty
    ELSE
        ThisItem <- Stack[TopPointer]
        TopPointer <- TopPointer - 1
        RETURN ThisItem
    ENDIF
ENDFUNCTION
Task — Worked Example — Trace push/pop
Trace. A stack of size 4 starts empty (top = -1). Show the array and top after: push(7), push(2), pop(), push(9).
Hint:
  • Step 1 — push(7): top -1→0, store 7.
  • Step 2 — push(2): top 0→1, store 2.
  • Step 3 — pop(): read 2, top 1→0.
  • Step 4 — push(9): top 0→1, store 9.
Your Turn — Your Turn — Trace push/pop
Trace. A stack of size 4 starts empty (top = -1). Show the array and top after: push(5), push(8), push(1), pop().
Hint:
  • push moves top up then stores; pop reads then moves top down.

26.5 Peek, isEmpty, Overflow & Underflow

Why are we doing this?
  • Half the marks on stack code come from guarding the operations.
  • A push must refuse when full (overflow); a pop must refuse when empty (underflow).
  • Forget the guard and your code crashes on the examiner's test data.

Peek shows the top value but leaves the stack unchanged — useful when you want to look before you leap. isEmpty is the guard pop relies on. Overflow and underflow are the two error states.

Key rule
  • Push guard: refuse when top = maxSize - 1 (full).
  • Pop/peek guard: refuse when top = -1 (empty).
  • The error response can be a message, a returned -1, or raising an exception — follow what the question asks for.
Exam tip:
  • If a question says “the function returns -1 if the stack is empty”, you must literally RETURN -1 — not print a message.
  • The -1 is a signal the calling code tests for.
  • Reading the question's exact error behaviour is worth a mark.

26.6 Building a Stack from a Linked List

Why are we doing this?
  • Mark scheme: The syllabus point “show how an ADT can be implemented from another ADT” is examined directly.
  • A stack does not need an array — it can be a linked list where the top is the head node.
  • Push adds a node at the front; pop removes the front node.
  • No fixed size, so no overflow.

Each node stores a value and a pointer to the next node. The stack keeps one pointer, top, aimed at the head. Push creates a new node whose next points to the old top, then moves top to the new node. Pop does the reverse.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None          # pointer to next node

class Stack:
    def __init__(self):
        self.top = None           # top = head node

    def push(self, item):
        newNode = Node(item)
        newNode.next = self.top   # link to old top
        self.top = newNode        # new node becomes top

    def pop(self):
        if self.top is None:
            return "Stack Underflow"
        item = self.top.value
        self.top = self.top.next  # head moves to next node
        return item

    def peek(self):
        return "Stack is empty" if self.top is None else self.top.value
Task — Worked Example — Three features of a linked-list stack [3 marks]
Explain (3 marks). Give three features that show a stack can be implemented from a linked list.
Hint:
  • Think about what a node holds, what the top pointer aims at, and how push/pop work.
Your Turn — Your Turn — Advantage and disadvantage of a linked-list stack [2 marks]
Explain (2 marks). State one advantage and one disadvantage of a linked-list stack compared with an array-based stack.
Hint:
  • Think about size limits and memory use.

26.7 Stack Applications & Practice

Why are we doing this?
  • Stacks appear “in disguise” in many Paper 4 tasks: reversing data, checking matched brackets, evaluating expressions, and supporting recursion (every recursive call is pushed onto the call stack).
  • Recognising when a stack is the right tool is itself an exam skill.
Task — Worked Example 20.1.1B — Reverse a string with a stack
Use a stack to reverse the string "STACK".
Hint:
  • Push every char, then pop them all — LIFO reverses the order.
Your Turn — Your Turn 20.1.1B — Palindrome test with a stack
Write a function that uses a stack to test whether a word is a palindrome (reads the same forwards and backwards), e.g. "madam".
Hint:
  • Reverse it with a stack, then compare to the original.
Task — Worked Example 20.1.1C — Balanced round brackets
Check whether a string of round brackets is balanced, e.g. "(())()".
Hint:
  • Push each “(”; pop on each “)”. Balanced if the stack ends empty.
Your Turn — Your Turn 20.1.1C — Balanced square and round brackets
Extend the idea to square brackets too: accept [] and (), where each closing bracket must match the most recent opening bracket. Test "([])" → True, "([)]" → False.
Hint:
  • Push the opening bracket; on a closing one, pop and check it is the matching type.
Task — Worked Example 20.1.1D — File to stack, print reversed
Read numbers from numbers.txt (one per line), push each onto a stack, then pop them to print in reverse order.
Hint:
  • Push each int(line.strip()), then while s: print(s.pop()).
Your Turn — Your Turn 20.1.1D — Vowels and consonants to two stacks
Read the text in text.txt and push every letter onto one of two stacks — vowels in one, consonants in the other. Then pop each stack to display its letters in reverse.
Hint:
  • if ch in "aeiou" decides which stack to push to.

26.8 Full Exam-Style Question

Paper 4 / Paper 3 · stack · ~12 marks
  • A program at moshikur.com uses a stack to hold up to 50 student ID numbers.
  • The stack is implemented with a 1D array IDStack[0:49] and an integer pointer Top.

(a) [1] State the value Top should hold when the stack is empty, and the rule used to decide it. (AO1)

(b) [4] The procedure Push(NewID) adds an ID if there is room, otherwise outputs "Stack full". Complete the pseudocode:

PROCEDURE Push(NewID : INTEGER)
    IF .................... THEN
        Top <- ....................
        .................... <- NewID
    ELSE
        OUTPUT "Stack full"
    ENDIF
ENDPROCEDURE

(c) [4] Write the function Pop() that returns the top ID, or returns -1 if the stack is empty, and updates the pointer. (AO3)

(d) [3] The stack currently holds, from bottom to top: 12, 19, 27 (Top = 2). Show the array contents and Top after this sequence: Push(31), Pop(), Pop(). (AO2)

Lab Task — Show mark scheme
Reveal the mark scheme for parts (a)–(d).
Hint:
  • (a) Top = -1 because no item occupies any index yet.
  • (b) IF Top < 49; Top <- Top + 1; IDStack[Top] <- NewID; increment before store.
  • (c) IF Top = -1 RETURN -1; ThisID <- IDStack[Top]; Top <- Top - 1; RETURN ThisID.
  • (d) Push(31): [12,19,27,31,…] Top=3; Pop: removes 31, Top=2; Pop: removes 27, Top=1.

Key Points Summary

A stack is a LIFO collection — every item is added and removed from the same end (the top). Last in, first out.
The top pointer records where the top item sits. When the stack is empty, top = -1 (no item at any index yet).
A push does top ← top + 1 FIRST, then stores the value. Order matters — get it backwards and you overwrite the current top.
A pop reads the value FIRST, then does top ← top - 1. Read before decrement — otherwise you lose the value.
The array-based Stack class uses a fixed-size list (items = [None] * size), a maxSize, and top = -1 in the constructor.
isEmpty() returns (top == -1) — the single source of truth for "empty". isFull() returns (top == maxSize - 1).
Push guard: refuse when top = maxSize - 1 (full = overflow). Pop/peek guard: refuse when top = -1 (empty = underflow).
peek() returns the top value without changing the pointer — look before you leap. It does not remove the item.
In Cambridge pseudocode: IF TopPointer < MaxSize - 1 for push; IF TopPointer = -1 (or BasePointer) for empty.
Pop often returns -1 when empty (a signal the calling code tests for). If the question says "returns -1", you must literally RETURN -1 — not print a message.
A stack can be built from a linked list: top points at the head node. Push adds a node at the front; pop removes the front node.
Linked-list push: create a new node, set newNode.next = top (link to old top), then top = newNode (new node becomes top).
Linked-list pop: read top.value, then top = top.next (head moves to next node). No fixed size, so no overflow until memory runs out.
Advantage of a linked-list stack: no fixed maximum size. Disadvantage: each node needs extra memory for its pointer.
Stack applications: reversing data, checking matched brackets, evaluating expressions, and supporting recursion (the call stack).
When tracing, always write the pointer value after each operation — a correct stack with a missing or wrong pointer still drops a mark.

26.9 Practice Tasks

Fifteen exam-style tasks. Click Hint for bullet-point guidance, then Help to reveal a worked Python solution.

1Practice Task — Declare a Stack class [4 marks]
Write a Stack class with a constructor that takes a size, creates a fixed-size list, stores maxSize, and sets top = -1.
2Practice Task — isEmpty and isFull [3 marks]
Write isEmpty() and isFull() methods for the Stack class.
3Practice Task — push method [4 marks]
Write the push(self, item) method that checks for overflow, moves the pointer up, and stores the item.
4Practice Task — pop method [4 marks]
Write the pop(self) method that checks for underflow, reads the value, blanks the slot, moves the pointer down, and returns the item.
5Practice Task — peek method [2 marks]
Write the peek(self) method that returns the top value without changing the pointer, or a message if empty.
6Practice Task — Trace push/pop [3 marks]
A stack of size 4 starts empty. After push(10), push(20), push(30), pop(), what is the array and top?
7Practice Task — Pseudocode Push [4 marks]
Write Cambridge pseudocode for PROCEDURE Push(NewItem : INTEGER) that checks for room, updates TopPointer, and stores the item, or outputs "Stack full".
8Practice Task — Pseudocode Pop [4 marks]
Write Cambridge pseudocode for FUNCTION Pop() RETURNS INTEGER that returns the top ID, or -1 if empty, and updates the pointer.
9Practice Task — Overflow or underflow? [3 marks]
A stack has maxSize = 3. (i) top = -1, call pop(); (ii) top = 2, call push(x); (iii) top = 0, call peek(). For each, state OK, Overflow, or Underflow.
10Practice Task — Linked-list Stack push [4 marks]
Write the push method for a linked-list Stack: create a new Node, link it to the old top, and make it the new top.
11Practice Task — Linked-list Stack pop [4 marks]
Write the pop method for a linked-list Stack: check for underflow, read the head value, move top to top.next, return the value.
12Practice Task — Reverse a string [4 marks]
Write a function reverse(text) that uses a stack (list) to reverse a string.
13Practice Task — Balanced brackets [5 marks]
Write a function balanced(expr) that uses a stack to check whether a string of round brackets is balanced.
14Practice Task — File to stack, print reversed [5 marks]
Read numbers from numbers.txt (one per line), push each onto a stack, then pop them to print in reverse order.
15Practice Task — Full exam-style: ID stack [12 marks]
A stack holds up to 50 student IDs in IDStack[0:49] with pointer Top. (a) State Top when empty [1]. (b) Write pseudocode Push(NewID) [4]. (c) Write pseudocode Pop() returning -1 if empty [4]. (d) Stack holds 12,19,27 (Top=2). Show array and Top after Push(31), Pop(), Pop() [3].

Question Bank

Answer all questions, then press Submit Quiz to see your score.

0/12 answered

Question 1Multiple Choice

A stack is a collection where:

Question 2Multiple Choice

When is the top pointer set to -1?

Question 3True / False

A push does top ← top + 1 first, then stores the value.

Question 4Multiple Choice

A pop does:

Question 5Multiple Choice

What is overflow?

Question 6Multiple Choice

What is underflow?

Question 7Multiple Choice

What does peek() do?

Question 8True / False

In Cambridge pseudocode, Pop returns -1 when the stack is empty.

Question 9Multiple Choice

In a linked-list stack, push adds a node:

Question 10Multiple Choice

A linked-list stack has what advantage over an array-based stack?

Question 11Multiple Choice

Trace: push(10), push(20), push(30), then pop(). What does pop return?

Question 12Multiple Choice

A stack of size 4 starts empty. After push(7), push(2), pop(), push(9), what is top?

Answer all 12 questions to enable submission.