A Level · Topic 19.1
A-Level Computer Science 9618 / Topic 19 / A2

Write the operations.

At A Level you must write the algorithms that make each abstract data type work: insert into and delete from a stack, a queue and a linked list, and insert into and find in a binary tree. You also describe dictionaries and graphs, and show how one ADT can be built from another.

The key idea

An abstract data type (ADT) is defined by its data and its operations, not by how it is stored. A stack (push, pop) needs an array and a top pointer; a circular queue (enqueue, dequeue) needs front and rear pointers that wrap round with MOD; a linked list needs an array of records with a start pointer, a free list pointer and a null pointer (−1) at the end; a binary search tree adds a left and a right pointer to each node, smaller values to the left. A dictionary stores key-value pairs, and a graph is a set of vertices joined by edges. ADTs can be built from other ADTs, for example a queue from two stacks.

A binary search tree and the array of records that stores it 503070 20456085 node 012 3456 left subtree smaller, right subtree larger RootPointer = 0, FreePointer = 7 IndexLeftDataRight 01502 13304 25706 3−120−1 4−145−1 5−160−1 6−185−1 78(free)−1
Fig. 1: a binary search tree of seven integers and the array of records that stores it; unused nodes form a free list through LeftPointer
Section 01

Stacks and queues in code.

In the lab, fill the circular queue, dequeue a few items and enqueue again: the rear pointer wraps round to index 0. The pseudocode below does exactly what the lab does, using a count to tell a full queue from an empty one.

DECLARE Stack : ARRAY[0:7] OF INTEGER
DECLARE TopPointer : INTEGER       // -1 when the stack is empty

PROCEDURE Push(Item : INTEGER)
    IF TopPointer = 7 THEN
        OUTPUT "Stack full"
    ELSE
        TopPointer ← TopPointer + 1
        Stack[TopPointer] ← Item
    ENDIF
ENDPROCEDURE

FUNCTION Pop() RETURNS INTEGER
    DECLARE Item : INTEGER
    IF TopPointer = -1 THEN
        OUTPUT "Stack empty"
        RETURN -1
    ENDIF
    Item ← Stack[TopPointer]
    TopPointer ← TopPointer - 1
    RETURN Item
ENDFUNCTION
DECLARE Queue : ARRAY[0:5] OF INTEGER
DECLARE FrontPointer : INTEGER     // starts at 0
DECLARE RearPointer : INTEGER      // starts at -1
DECLARE NumberInQueue : INTEGER    // starts at 0

PROCEDURE Enqueue(Item : INTEGER)
    IF NumberInQueue = 6 THEN
        OUTPUT "Queue full"
    ELSE
        RearPointer ← (RearPointer + 1) MOD 6
        Queue[RearPointer] ← Item
        NumberInQueue ← NumberInQueue + 1
    ENDIF
ENDPROCEDURE

FUNCTION Dequeue() RETURNS INTEGER
    DECLARE Item : INTEGER
    IF NumberInQueue = 0 THEN
        OUTPUT "Queue empty"
        RETURN -1
    ENDIF
    Item ← Queue[FrontPointer]
    FrontPointer ← (FrontPointer + 1) MOD 6
    NumberInQueue ← NumberInQueue - 1
    RETURN Item
ENDFUNCTION
Worked example Trace the circular queue
The queue above starts empty. Trace Enqueue 10, 20, 30, 40, 50; Dequeue three times; then Enqueue 60, 70, 80. Give the final pointers and the queue in order.
  1. Five enqueues: RearPointer goes 0, 1, 2, 3, 4 and NumberInQueue = 5.
  2. Three dequeues return 10, 20, 30; FrontPointer = 3 and NumberInQueue = 2.
  3. Enqueue 60: RearPointer = 5. Enqueue 70: RearPointer = (5 + 1) MOD 6 = 0, into the space 10 left.
  4. Enqueue 80: RearPointer = 1. NumberInQueue = 5.
Answer: FrontPointer = 3, RearPointer = 1, NumberInQueue = 5; the queue from front to rear is 40, 50, 60, 70, 80 (indices 3, 4, 5, 0, 1)
Your turn
A queue is built from two stacks, InStack and OutStack. Enqueue pushes onto InStack. Dequeue pops from OutStack, but if OutStack is empty it first pops every item from InStack and pushes it onto OutStack. Trace Enqueue A, B, C; Dequeue; Enqueue D; then Dequeue three times.
Examiner trap

In a circular queue, write (RearPointer + 1) MOD 6, not RearPointer + 1. Without MOD the pointer runs past index 5 even though spaces at the front are free.

Section 02

Linked lists in code.

In the lab, insert and delete items and watch only the pointers change. Below, the list is an array of records, each with a Data field and a Pointer field. The table shows the starting state used in the examples.

IndexDataPointer
0Cole6
1Ava4
25
3Eli−1
4Bea0
57
6Dan3
7−1

StartPointer = 1, FreeListPointer = 2. The list is Ava → Bea → Cole → Dan → Eli → null; the free list is 2 → 5 → 7 → null.

TYPE ListNode
    DECLARE Data : STRING
    DECLARE Pointer : INTEGER
ENDTYPE
DECLARE List : ARRAY[0:7] OF ListNode
DECLARE StartPointer : INTEGER
DECLARE FreeListPointer : INTEGER
CONSTANT NullPointer = -1

FUNCTION FindItem(SearchItem : STRING) RETURNS INTEGER
    DECLARE Current : INTEGER
    Current ← StartPointer
    WHILE Current <> NullPointer
        IF List[Current].Data = SearchItem THEN
            RETURN Current
        ENDIF
        Current ← List[Current].Pointer
    ENDWHILE
    RETURN NullPointer
ENDFUNCTION

PROCEDURE DeleteItem(DeleteThis : STRING)
    DECLARE Current : INTEGER
    DECLARE Previous : INTEGER
    DECLARE Found : BOOLEAN
    Current ← StartPointer
    Previous ← NullPointer
    Found ← FALSE
    WHILE Current <> NullPointer AND Found = FALSE
        IF List[Current].Data = DeleteThis THEN
            Found ← TRUE
        ELSE
            Previous ← Current
            Current ← List[Current].Pointer
        ENDIF
    ENDWHILE
    IF Found = TRUE THEN
        IF Previous = NullPointer THEN
            StartPointer ← List[Current].Pointer
        ELSE
            List[Previous].Pointer ← List[Current].Pointer
        ENDIF
        List[Current].Pointer ← FreeListPointer
        FreeListPointer ← Current
    ENDIF
ENDPROCEDURE
Worked example Delete from the middle
Using the table, trace DeleteItem("Cole"). Which values change?
  1. Current = 1 (Ava), not a match: Previous = 1, Current = 4.
  2. Current = 4 (Bea), not a match: Previous = 4, Current = 0.
  3. Current = 0 (Cole): Found = TRUE. Previous is not null, so List[4].Pointer ← List[0].Pointer = 6: Bea now points to Dan.
  4. Node 0 joins the front of the free list: List[0].Pointer ← 2 and FreeListPointer ← 0.
Answer: List[4].Pointer = 6, List[0].Pointer = 2, FreeListPointer = 0; StartPointer stays 1. The list is Ava, Bea, Dan, Eli
Your turn
Start again from the table. Write the steps (in words or pseudocode) to insert Abe at the start of the list, and give the new values of StartPointer and FreeListPointer.
Examiner trap

Deleting the first node is a special case: there is no previous node, so the start pointer must change. Code that only updates List[Previous].Pointer fails for it.

Stage 1 · Learn

Check what the sim just showed you

Four quick checks. Each correct answer earns XP and records this skill on your profile.

Quick check+10 XP

In the lab's circular queue of 6 elements, RearPointer is 5. Where does the next item go if the queue is not full?

Quick check+10 XP

What must Pop check before it changes TopPointer?

Quick check+10 XP

When a node is deleted from a linked list, what happens to that node?

Quick check+10 XP

In the lab's binary search tree, where is a value equal to the root placed?

Section 03

Trees, dictionaries and graphs.

In the lab, insert a value into the binary tree and watch the comparisons from the root: left if smaller, right if larger or equal, until a null pointer is found. The new node is attached there. Then search for a value that is not in the tree.

TYPE TreeNode
    DECLARE LeftPointer : INTEGER
    DECLARE Data : INTEGER
    DECLARE RightPointer : INTEGER
ENDTYPE
DECLARE Tree : ARRAY[0:9] OF TreeNode
DECLARE RootPointer : INTEGER
DECLARE FreePointer : INTEGER
CONSTANT NullPointer = -1

PROCEDURE InsertNode(NewItem : INTEGER)
    DECLARE NewNode : INTEGER
    DECLARE Current : INTEGER
    DECLARE Previous : INTEGER
    DECLARE GoLeft : BOOLEAN
    IF FreePointer = NullPointer THEN
        OUTPUT "Tree full"
    ELSE
        NewNode ← FreePointer
        FreePointer ← Tree[NewNode].LeftPointer
        Tree[NewNode].Data ← NewItem
        Tree[NewNode].LeftPointer ← NullPointer
        Tree[NewNode].RightPointer ← NullPointer
        IF RootPointer = NullPointer THEN
            RootPointer ← NewNode
        ELSE
            Current ← RootPointer
            WHILE Current <> NullPointer
                Previous ← Current
                IF NewItem < Tree[Current].Data THEN
                    GoLeft ← TRUE
                    Current ← Tree[Current].LeftPointer
                ELSE
                    GoLeft ← FALSE
                    Current ← Tree[Current].RightPointer
                ENDIF
            ENDWHILE
            IF GoLeft = TRUE THEN
                Tree[Previous].LeftPointer ← NewNode
            ELSE
                Tree[Previous].RightPointer ← NewNode
            ENDIF
        ENDIF
    ENDIF
ENDPROCEDURE
Worked example Insert into the tree
Starting from the tree in Fig. 1 (FreePointer = 7), insert 40 and then 65. Give the node used and the pointer that changes for each.
  1. 40: node 7 is taken and FreePointer ← Tree[7].LeftPointer = 8.
  2. 40 < 50 go left to node 1 (30); 40 > 30 go right to node 4 (45); 40 < 45 go left, which is null. So Tree[4].LeftPointer ← 7.
  3. 65: node 8 is taken and FreePointer ← 9.
  4. 65 > 50 go right to node 2 (70); 65 < 70 go left to node 5 (60); 65 > 60 go right, which is null. So Tree[5].RightPointer ← 8.
Answer: 40 goes in node 7 as the left child of 45; 65 goes in node 8 as the right child of 60; FreePointer = 9
Your turn
After those two inserts, search the tree for 48. Which values are compared, and how does the search end?
Examiner trap

When inserting into a tree or a linked list, take the node from the free list and update the free pointer before setting the new node's own pointers, or the rest of the free list is lost.

Stage 2 · Exam

Exam-style questions

Unlocks once the four checks above are done. Worth more XP, written to A Level Paper 3 and Paper 4 standard.

Finish the four checks above to unlock the exam questions
Exam style+20 XP

Which ADT is most suitable for storing English words with their French translations?

Exam style+20 XP

Which is a key feature of a graph?

Exam style+20 XP

A binary search tree is built by inserting 10, 20, 30, 40, 50 in that order. What is the problem?

Exam style+20 XP

A stack is implemented using a linked list. Where should Push insert the new node?

Skill unlocked

Abstract data types, mastered.

This skill is now recorded on your profile. Keep the chain going.

-Rank -Level -Score -Topics
Go deeper · practice
Six original Cambridge-style questions
Writing insert, delete and find algorithms for stacks, queues, linked lists and binary trees, and describing dictionaries and graphs.