29.1 Introduction: The Binary Tree ADT
You have already met the linked list, where each node points to one next node, making a straight line. A binary tree changes one thing: each node may point to two nodes — a left child and a right child. That single change turns a line into a branching shape, like a family tree drawn upside down.
The version you must know is the ordered binary tree (also called a binary search tree). It follows one rule whenever a value is added: anything smaller than a node goes into its left branch, anything larger goes into its right branch. Because the data is sorted by that rule as it is inserted, finding a value later means you can throw away half the tree at every step — which is exactly why trees are fast to search.
By the end of this page you will be able to draw a tree as values arrive, build the Node and BinaryTree classes, insert and find values, and explain why reading the tree “in order” prints everything sorted.
- The binary tree ADT: describing it, building it, inserting, finding, and in-order traversal.
- The syllabus does not require you to delete from a binary tree — only insert and find.
- Searching theory (efficiency / Big-O) is in the algorithms chapter.
| Term | Meaning |
|---|---|
| root | The single node at the very top of the tree — the entry point. Everything is reached by starting here. |
| node | One item in the tree: a data value plus a left pointer and a right pointer. |
| child | A node hanging directly below another. Each node has up to two: a left child and a right child. |
| parent | The node directly above a child. The root has no parent. |
| leaf | A node with no children — both its pointers are null. Leaves are the "ends" of the tree. |
| subtree | Any node together with everything hanging below it. A tree is made of smaller trees — which is why recursion fits so well. |
| ordered (BST) | The rule that smaller values go left and larger values go right, keeping the data sorted as it is inserted. |
| in-order traversal | Visiting left subtree, then the node, then right subtree. On an ordered tree this gives the data in sorted order. |
29.2 Root, Children, Leaves & the Ordering Rule
- Cambridge often shows a tree diagram and asks you to label the
root, aleaf, or to add values in the correct positions. - If you can read and draw the shape confidently, the coding later is just writing down what you can already see.
Picture the tree below. Mehrin enters these student marks one at a time into the revision tracker: 50, 30, 70, 20, 40, 60. The first value, 50, becomes the root. After that, every new value starts at the root and turns left (smaller) or right (larger) until it finds an empty spot, where it settles as a new leaf.
Ordered binary tree after inserting 50, 30, 70, 20, 40, 60
- Start at the root for every insertion or search.
- At each node: if your value is smaller, go left; if it is larger, go right.
- Stop when you reach an empty (null) branch.
- When asked to “complete the diagram” by adding values, write each value's path lightly first (L / R at each node).
- Examiners award the mark for the correct final position, so a wrong turn early loses the mark even if the rest looks neat.
29.2 Root, Children, Leaves & the Ordering Rule
29.3 The Node and BinaryTree Classes
- The cleanest Python model gives each
Nodetwo references —leftandright— that point at otherNodeobjects or atNone. - This is the version you will run, and it makes insert and search short because each subtree is just another tree.
class Node:
def __init__(self, data):
self.data = data # the value stored
self.left = None # left child (smaller)
self.right = None # right child (larger)
class BinaryTree:
def __init__(self):
self.root = None # empty tree
def insert(self, value):
if self.root is None:
self.root = Node(value) # first value becomes the root
else:
self._insert(self.root, value)
def _insert(self, current, value):
if value < current.data: # smaller -> go left
if current.left is None:
current.left = Node(value)
else:
self._insert(current.left, value)
else: # larger (or equal) -> go right
if current.right is None:
current.right = Node(value)
else:
self._insert(current.right, value)Read the _insert method as a sentence: “if the value is smaller than this node, deal with the left side; otherwise deal with the right side.” Each time, if the branch is empty (None) we drop the new node there; if not, we ask the same question one node further down. That “ask the same question further down” is recursion.
- Every new value always becomes a leaf.
- Insertion never rearranges existing nodes — it only follows left/right turns until it meets an empty branch.
29.3 The Node and BinaryTree Classes
29.4 Inserting a Value
- Mark scheme: “Add a new item to the tree” is a classic Paper 3 / Paper 4 task (e.g. the binary-tree ADT in 9618/32 specimen Q7).
- The marks go to the correct comparison and the correct pointer being set, so tracing carefully is the whole skill.
Tracing an insert means walking from the root and writing down each decision. Below, Aymaan inserts 45 into the tree from Section 2.
- Start at the root. At each node: smaller go left, larger go right. Stop at an empty branch.
- Start at the root every time, and remember larger goes right.
29.4 Inserting a Value
29.5 Finding a Value
- Searching a binary tree reuses the exact same left/right logic as insertion — but instead of dropping a node, you report found / not found.
- The syllabus specifically asks you to “write an algorithm to find an item in a binary tree.”
def find(self, target):
current = self.root
while current is not None:
if target == current.data:
return True # found it
elif target < current.data:
current = current.left # smaller -> left subtree
else:
current = current.right # larger -> right subtree
return False # fell off the tree -> not presentEach comparison lets you ignore an entire subtree, so on a well-shaped tree you check far fewer than every node. The loop ends two ways: a match (True), or running off the bottom into None (False).
- Start at the root; compare; go left or right; stop on match or None.
- The loop stops when current becomes None.
- If a tree is built from data that arrives already sorted, it degrades into a single long branch — effectively a linked list — and search is no faster than checking every item.
- Mentioning this trade-off earns the higher-level mark in “evaluate” questions.
29.5 Finding a Value
29.6 In-Order Traversal (Reading It Sorted)
- “Traverse the tree” appears repeatedly in the specimen and past papers.
- The most useful traversal is in-order, because on an ordered tree it always outputs the data in ascending order — a neat way to sort.
In-order means: for any node, first deal with its left subtree, then visit the node itself, then its right subtree. Because left always holds smaller values, you naturally print from smallest to largest.
def in_order(self, node):
if node is not None:
self.in_order(node.left) # 1. left subtree
print(node.data, end=" ") # 2. this node
self.in_order(node.right) # 3. right subtree
# In-order traversal of 50, 30, 70, 20, 40, 60 produces:
# 20 30 40 50 60 70 -- sorted ascending!- Left subtree of 50 first → 30-subtree gives 20, 30, 40. Then 50. Then right subtree → 60, 70.
- You don't need to draw it; in-order on an ordered tree is just the values sorted.
29.6 In-Order Traversal & the Array Model
29.7 The Array-of-Records Model (ADT from Another ADT)
- Mark scheme: Cambridge often asks you to implement a tree without object references — as a 1D array of records, each with a left pointer and a right pointer holding array indices (see 9618/03 specimen Q7).
- This shows a tree built from a linked list of records — one ADT from another.
Each node is a record: Data, LeftPointer, RightPointer. A RootPointer stores the index of the root; a FreePointer tracks the next unused slot. The null pointer is -1 (or 0 if the array starts at 1). Below is the tree 50, 30, 70 stored this way.
| Index | Data | LeftPointer | RightPointer | role |
|---|---|---|---|---|
| 0 | 50 | 1 | 2 | root |
| 1 | 30 | -1 | -1 | leaf |
| 2 | 70 | -1 | -1 | leaf |
RootPointer = 0. Node 0 (the root, 50) points left to index 1 (30) and right to index 2 (70). Both 30 and 70 are leaves (their pointers are -1).
- A binary tree is built from a linked list of records: each record (node) is linked to others by index pointers, exactly like a linked list, but with two pointers instead of one.
- This is the “implement an ADT from another ADT” point examiners look for.
29.8 Full Exam-Style Question
- moshikur.com stores unique student ID numbers in an ordered binary tree so they can be searched quickly.
- Each
Noderecord has fieldsData,LeftPointerandRightPointer. RootPointerindexes the root and the null pointer is-1.
(a) [2] Describe two features of a binary tree ADT. (AO1)
(b) [3] The IDs 500, 300, 800, 200, 400 are inserted in that order. Draw the resulting ordered binary tree. (AO2)
(c) [4] Complete the function FindID(Target) that returns the index of the node holding Target, or -1 if absent. (AO2)
FUNCTION FindID(Target) RETURNS INTEGER
ThisPtr <- ....................
WHILE ThisPtr <> -1
IF Tree[ThisPtr].Data = Target THEN
RETURN ....................
ELSEIF Target < Tree[ThisPtr].Data THEN
ThisPtr <- ....................
ELSE
ThisPtr <- ....................
ENDIF
ENDWHILE
RETURN -1
ENDFUNCTION(d) [2] State the output of an in-order traversal of the tree in part (b), and explain why it is in this order. (AO2)
(e) [2] Explain one disadvantage of a binary tree if the IDs happen to be inserted in ascending order. (AO3)
- (a) 2 from: node = data + two pointers; one root; ordered smaller-left/larger-right; leaves null; hierarchical.
- (b) 500 root; 300 left, 800 right; 200 left of 300; 400 right of 300.
- (c) ThisPtr ← RootPointer; RETURN ThisPtr; ThisPtr ← Tree[ThisPtr].LeftPointer; ThisPtr ← Tree[ThisPtr].RightPointer.
- (d) 200 300 400 500 800; in-order visits left (smaller) then node then right (larger) = ascending.
- (e) tree becomes one long branch (like a linked list); search no faster than checking every node.
✓ Key Points Summary
29.9 Practice Tasks
Fifteen exam-style tasks. Click Hint for bullet-point guidance, then Help to reveal a worked Python/pseudocode solution.
Question Bank
Answer all questions, then press Submit Quiz to see your score.
Question 1Multiple Choice
A binary tree gives every node up to:
Question 2Multiple Choice
In an ordered binary tree (BST), where does a larger value go?
Question 3True / False
The first value inserted into a binary tree becomes the root.
Question 4Multiple Choice
What is a leaf?
Question 5Multiple Choice
In the Node class, what are the three fields?
Question 6Multiple Choice
When inserting, every new value:
Question 7Multiple Choice
In find, if target < current.data, which way do you go?
Question 8True / False
In-order traversal visits left subtree, then the node, then right subtree.
Question 9Multiple Choice
In-order traversal of an ordered binary tree outputs values in what order?
Question 10Multiple Choice
In the Cambridge array model, what does each node record have?
Question 11Multiple Choice
If data arrives already sorted, the binary tree:
Question 12Multiple Choice
A binary tree built from a linked list of records (two pointers per node) is an example of:
Answer all 12 questions to enable submission.