Skip to topic
    ← Back to course topics

    Abstract data types/data structures — AQA A-Level Computer Science

    An Abstract Data Type (ADT) is a logical description of how data is viewed and manipulated, defined by its behaviour and operations rather than its concrete implementation. In AQA A-Level Computer Science, mastering ADTs such as stacks, queues, trees, graphs, and hash tables requires understanding their static versus dynamic implementations and algorithmic efficiencies.

    Abstract data types/data structures explained

    A stack is an abstract data type that stores items in a last in, first out (LIFO) order.

    Read the full explanation

    Items are added to the top with a push operation and removed from the top with a pop operation, so the most recently added item is always the first to be removed. Stacks are often implemented as an array with a pointer to the top element, or as a linked list where the head node is the top. A typical use is tracking return addresses for subroutine calls, where the most recent call must return first. Because access is restricted to the top, a stack does not allow direct access to items deeper in the structure. Understanding the operations and their order of effect is the key to answering questions about stacks correctly.

    What to demonstrate

    1. Identifies the stack as LIFO, meaning the last item pushed is the first item popped.
    2. Describes push as adding an item to the top and pop as removing the item from the top.
    3. Recognises that only the top element is directly accessible at any time.
    Show all 4 objectives
    1. Links the stack to a practical use such as subroutine return addresses or undo functionality.

    Which command word is this?

    Set out the mathematical or logical reasons for how an ADT operates or why a specific implementation is chosen, connecting causes to computational consequences.

    Abstract data types/data structures exam tips

    Topic Overview

    Abstract Data Types (ADTs) provide high-level models of data storage that encapsulate data representation behind well-defined operational interfaces. In AQA A-Level Computer Science, this topic explores both the conceptual mechanics and the practical implementations of stacks, queues, linked lists, trees, graphs, hash tables, and dictionaries.

    Understanding ADTs bridges the gap between software design and algorithmic efficiency. Selecting the correct data structure directly governs the time and space complexity of computational solutions, forming a foundational component of Paper 1 and Paper 2 assessment objectives.

    Key Concepts
    • →Abstraction vs Implementation: An ADT describes what operations can be performed (e.g., push, pop, peek), whereas a data structure represents how those operations are physically stored in memory.
    • →Static vs Dynamic Data Structures: Static structures have fixed memory allocations determined at compile time (e.g., fixed-size arrays), while dynamic structures allocate memory from the heap at runtime using pointers.
    • →Linear vs Non-Linear Structures: Stacks, queues, and linked lists store elements sequentially, while trees and graphs represent non-linear hierarchical or interconnected network relationships.
    • →Collision Resolution in Hash Tables: Techniques such as open addressing (linear probing) and closed addressing (chaining with linked lists) resolve scenarios where two distinct keys hash to the same index.
    Marking Points
    • Identifies the stack as LIFO, meaning the last item pushed is the first item popped.
    • Describes push as adding an item to the top and pop as removing the item from the top.
    • Recognises that only the top element is directly accessible at any time.
    • Links the stack to a practical use such as subroutine return addresses or undo functionality.
    Examiner Tips
    • 💡Trace a short sequence of push and pop operations step by step on paper to check the final contents.
    • 💡Remember that the most recently pushed item is always the next one popped.
    • 💡When an MCQ asks about removal order, check whether the answer option reflects last in, first out.
    • 💡When drawing or tracing pointer operations for linked lists and trees, explicitly label pointer variables (e.g. 'Head', 'Prev', 'Curr') and denote null pointers clearly using ground symbols or the value 'null'.
    • 💡Always state time complexities using Big-O notation when comparing operations across structures (e.g., hash table retrieval is O(1) average case, whereas unindexed linked list search is O(n)).
    • 💡In pseudocode questions, remember to implement defensive programming checks: verify 'isFull()' before pushing/enqueueing and 'isEmpty()' before popping/dequeueing.
    Common Mistakes
    • Treats a stack as FIFO, which is the behaviour of a queue; correct by remembering that a stack reverses the order of arrival.
    • Assumes items can be removed from the bottom or middle; correct by restricting removal to the top only.
    • Confuses push and pop, or reverses their effects; correct by linking push to adding and pop to removing from the top.
    • Assuming dynamic data structures are always superior to static data structures. While dynamic structures avoid overflow and conserve unused memory, they incur memory overhead for pointer storage and lack direct random index access.
    • Believing a circular queue moves items in memory during dequeue operations. Circular queues use modulo arithmetic to advance pointer indices; the existing data elements are not physically shifted.
    • Confusing graph traversals with tree traversals. Graphs may contain cycles and disconnected components, requiring a 'visited' set or boolean flags to prevent infinite loops during BFS or DFS traversals.
    Revision Plan
    1. 1Day 1-3: Master linear ADTs. Code and trace stacks, linear queues, circular queues, and priority queues using static arrays and dynamic linked lists.
    2. 2Day 4-6: Study non-linear structures. Practice manual insertion, deletion, and tree traversals (pre-order, in-order, post-order) for binary search trees.
    3. 3Day 7-9: Explore graphs and hash tables. Implement adjacency matrices vs adjacency lists, hash functions, and collision resolution strategies.
    4. 4Day 10-12: Solve past AQA exam questions focusing on 6-mark comparative essays, pointer-trace diagrams, and pseudocode algorithms.
    Exam Question Types
    • 📋Trace and diagram questions: Filling tables or drawing diagrams to trace pointers, stack frames, or queue indices across sequential operations.
    • 📋Algorithm implementation: Writing or completing pseudocode for core operations like tree insertions, linked list deletions, or hash table lookups.
    • 📋Comparative analysis: Evaluating trade-offs between static vs dynamic structures or adjacency matrices vs adjacency lists for specific application contexts.
    Command Word Expectations (AQA)
    Explain

    Set out the mathematical or logical reasons for how an ADT operates or why a specific implementation is chosen, connecting causes to computational consequences.

    Compare

    Identify both similarities and differences between two data structures (e.g. static vs dynamic, array vs linked list), referring to memory usage, runtime complexity, and ease of implementation.

    Write an algorithm

    Produce syntactically consistent pseudocode or structured English detailing exact steps, variable initialization, conditionals, pointer manipulations, and boundary checks.

    How Students Lose Marks (Examiner Pitfalls)
    Pitfall: Confusing the abstract definition of an ADT with its underlying physical implementation in memory.
    ❌ Weak Answer (Loses Marks):A queue is an array where the first item entered is the first item removed.
    Example improved answer:A queue is a First-In, First-Out (FIFO) abstract data type defined by operations such as enqueue and dequeue. While it can be implemented concretely using a fixed-size 1D array with front and rear pointers (static circular queue) or a linked list (dynamic queue), the abstract definition specifies behaviour independently of storage.
    Examiner Tip: Always separate the logical behaviour (e.g. FIFO, LIFO, hierarchical) from concrete implementation details (e.g. arrays, pointers, memory reallocation).
    Pitfall: Failing to account for pointer updates and boundary conditions when manipulating dynamic linear structures like linked lists or circular queues.
    ❌ Weak Answer (Loses Marks):To delete a node, just change the pointer to the next node and free memory.
    Example improved answer:To delete a target node in a singly linked list: traverse with a current pointer while maintaining a previous pointer until target is found; check if the node is the head (updating head pointer to current.next) or an internal node (setting previous.next to current.next); handle edge cases such as empty lists or node-not-found exceptions before reclaiming memory.
    Examiner Tip: Write explicit pseudocode checking for empty structures (underflow) and full structures (overflow for static forms) before executing insertion or deletion operations.
    Step-by-Step Worked Solutions

    Question: A circular queue of capacity 5 is implemented using a 0-indexed static array named 'queueArray', with integer pointers 'front' and 'rear', and an integer 'size'. Initially, the queue is empty: front = 0, rear = -1, size = 0. Show the internal state of the array and pointers after the following sequence of operations: enqueue('A'), enqueue('B'), enqueue('C'), dequeue(), enqueue('D'), enqueue('E'), dequeue(), enqueue('F').

    1. 1.Step 1: Understand formulas for circular queues: rear = (rear + 1) mod capacity upon enqueue; front = (front + 1) mod capacity upon dequeue; size tracks current item count.
    2. 2.Step 2: Trace operations: enqueue('A') sets queueArray[0]='A', rear=0, size=1. enqueue('B') sets queueArray[1]='B', rear=1, size=2. enqueue('C') sets queueArray[2]='C', rear=2, size=3.
    3. 3.Step 3: Process dequeue(): removes 'A', front becomes (0+1) mod 5 = 1, size=2.
    4. 4.Step 4: Process enqueue('D'): rear becomes (2+1) mod 5 = 3, queueArray[3]='D', size=3. Process enqueue('E'): rear becomes (3+1) mod 5 = 4, queueArray[4]='E', size=4.
    5. 5.Step 5: Process dequeue(): removes 'B', front becomes (1+1) mod 5 = 2, size=3.
    6. 6.Step 6: Process enqueue('F'): rear wraps around: (4+1) mod 5 = 0, queueArray[0]='F', size=4.
    7. 7.Step 7: Final array state: index 0 = 'F', index 1 = empty/stale ('B'), index 2 = 'C', index 3 = 'D', index 4 = 'E'.
    Final Answer: queueArray = ['F', empty, 'C', 'D', 'E']; front = 2 (pointing to 'C'); rear = 0 (pointing to 'F'); size = 4.

    Question: Given the following values to be inserted into an initially empty binary search tree (BST) in order: [47, 23, 65, 12, 38, 54, 78, 31]. Describe the construction of the tree, determine the height of the resulting tree (counting root as height 0), and list the nodes in post-order traversal.

    1. 1.Step 1: Insert 47 as root.
    2. 2.Step 2: 23 < 47 (left child of 47). 65 > 47 (right child of 47).
    3. 3.Step 3: 12 < 47 and 12 < 23 (left child of 23). 38 < 47 and 38 > 23 (right child of 23).
    4. 4.Step 4: 54 > 47 and 54 < 65 (left child of 65). 78 > 47 and 78 > 65 (right child of 65).
    5. 5.Step 5: 31 < 47, 31 > 23, 31 < 38 (left child of 38).
    6. 6.Step 6: Identify levels: Level 0: 47; Level 1: 23, 65; Level 2: 12, 38, 54, 78; Level 3: 31. Height is 3.
    7. 7.Step 7: Post-order traversal rule is Left-Right-Root recursively: Left subtree of root (rooted at 23): Left is 12; Right subtree is 38 (which has left 31, right null, root 38 -> 31, 38); Root is 23. Yields: 12, 31, 38, 23. Right subtree of root (rooted at 65): Left is 54; Right is 78; Root is 65. Yields: 54, 78, 65. Root is 47.
    Final Answer: Resulting tree has height 3. Post-order traversal sequence: 12, 31, 38, 23, 54, 78, 65, 47.
    Active Recall Memory Test
    What primary disadvantage does linear probing introduce in hash tables, and how does it degrade performance?
    Key Fact: It causes primary clustering, where occupied slots clump together, increasing average search and insertion times toward O(n).
    Which graph representation is more memory efficient for a sparse graph with V vertices and E edges?
    Key Fact: An adjacency list, which consumes O(V + E) space compared to O(V^2) for an adjacency matrix.
    In an in-order traversal of a valid Binary Search Tree (BST), what property does the resulting output sequence always exhibit?
    Key Fact: The keys are visited in strictly ascending (sorted) numerical or alphabetical order.
    Why can dynamic data structures lead to memory fragmentation?
    Key Fact: Nodes are allocated and deallocated arbitrarily across heap memory, leaving non-contiguous gaps of unused memory.
    Frequently Asked Questions
    What is the difference between an abstract data type and a concrete data structure?
    An Abstract Data Type (ADT) is a conceptual model that specifies what data is stored and what operations can be carried out on it, completely independent of code. A concrete data structure is the actual physical implementation of that ADT in computer memory using programming language constructs like arrays, pointers, or records.
    When should I choose an adjacency matrix over an adjacency list for graph representation?
    Choose an adjacency matrix when the graph is dense (has a high ratio of edges to vertices) or when constant-time O(1) edge lookup is required. Conversely, choose an adjacency list when the graph is sparse, as it saves substantial memory and allows faster iteration over a vertex's immediate neighbours.
    Why is a circular queue preferred over a simple linear queue implemented with an array?
    In a simple static array queue, dequeueing leaves empty memory slots at the front that cannot be reused without shifting every remaining element left, which takes O(n) time. A circular queue avoids shifting entirely by allowing pointers to wrap back to index 0 using modulo arithmetic, maintaining O(1) enqueue and dequeue operations.
    How does a priority queue differ from a standard FIFO queue?
    In a standard queue, elements are removed strictly in the order they arrived (First-In, First-Out). In a priority queue, each element has an associated priority value, and the item with the highest priority is always dequeued before items with lower priority, regardless of their arrival sequence.
    What causes stack overflow and stack underflow?
    Stack overflow occurs when a program attempts to push an item onto a stack that has already reached its maximum allocated memory limit, often caused by infinite recursion. Stack underflow occurs when an operation attempts to pop or peek an item from a completely empty stack.