Show understanding of recursion – its definition, structure, execution model, and how it is applied in algorithm design – as required by Cambridge International AS & A Level Computer Science (9618) syllabus point 19.2.
Recursion is a programming technique in which a method (or function) calls itself, either directly or indirectly, to solve a problem. The original problem is repeatedly reduced to smaller instances of the same problem until a simple case – the base case – can be solved directly.
When a recursive method is invoked, a new activation record (stack frame) is pushed onto the call stack. A frame typically contains:
When the method returns, its frame is popped and control resumes in the caller’s frame.
Example call‑stack for factorial(4) (ASCII diagram):
+-------------------+ // call factorial(4)
| n = 4 |
| return address → |
+-------------------+
| n = 3 | // call factorial(3)
| return address → |
+-------------------+
| n = 2 | // call factorial(2)
| return address → |
+-------------------+
| n = 1 | // call factorial(1)
| return address → |
+-------------------+
| n = 0 | // base case reached
| return 1 |
+-------------------+
Frames are popped in reverse order, producing the result 4 × 3 × 2 × 1 = 24.
Mathematical definition:
\$\$
n! =
\begin{cases}
1 & \text{if } n = 0\\[2mm]
n \times (n-1)! & \text{if } n > 0
\end{cases}
\$\$
public static long factorial(int n) {
// base case
if (n == 0) {
return 1L;
}
// recursive case – progress by decreasing n
return n * factorial(n - 1);
}
Mathematical definition:
\$\$
F_n =
\begin{cases}
0 & \text{if } n = 0\\[2mm]
1 & \text{if } n = 1\\[2mm]
F{n-1} + F{n-2} & \text{if } n \ge 2
\end{cases}
\$\$
public static long fib(int n) {
// base cases
if (n == 0) {
return 0L;
}
if (n == 1) {
return 1L;
}
// recursive case – two smaller sub‑problems
return fib(n - 1) + fib(n - 2);
}
Note: Exponential time‑complexity; for large n a memoised or iterative version is preferred.
public static int binarySearch(int[] A, int key, int low, int high) {
// base case – interval empty
if (low > high) {
return -1; // not found
}
int mid = low + (high - low) / 2; // avoid overflow
if (A[mid] == key) {
return mid; // found
} else if (key < A[mid]) {
return binarySearch(A, key, low, mid - 1); // search left half
} else {
return binarySearch(A, key, mid + 1, high); // search right half
}
}
public static void inorder(Node root) {
if (root == null) { // base case
return;
}
inorder(root.left); // left sub‑tree
System.out.println(root.data); // visit node
inorder(root.right); // right sub‑tree
}
Node class (simplified):
private static class Node {
int data;
Node left, right;
Node(int d) { data = d; }
}
A recursive call is in tail position when it is the last operation performed by the method. Some languages can replace the call with a jump (tail‑call optimisation), eliminating extra stack frames. Java does not guarantee this optimisation.
public static long factorialTail(int n) {
return factorialHelper(n, 1L);
}
/* private helper – not part of the public API */
private static long factorialHelper(int n, long acc) {
if (n == 0) { // base case
return acc;
}
// tail call – accumulator updated before the recursive call
return factorialHelper(n - 1, n * acc);
}
The helper method is private because it is an implementation detail; the public API remains simple, matching typical Cambridge exam expectations.
| Aspect | Recursion | Iteration |
|---|---|---|
| Code clarity for divide‑and‑conquer problems | Usually mirrors the mathematical definition; concise. | Often more verbose; explicit stack or auxiliary data structures needed. |
| Memory usage | One stack frame per call (depth = number of recursive levels). Typical worst‑case space = O(n). | Constant stack space; any extra memory is explicit (e.g., arrays). |
| Performance overhead | Function‑call overhead at each level. | Loop control overhead is minimal. |
| Tail‑call optimisation | Possible only if language/runtime guarantees it (Java does not). | Not applicable. |
| Ease of proving correctness | Inductive proofs align directly with the recursive definition. | Requires loop invariants; can be less intuitive. |
factorial(-1) or negative indices in binary search).factorial(3) or binary search on a 5‑element array). Use a diagram or a numbered list of frames.while/for loop and any required accumulator variables.Recursion is a powerful technique for problems that can be expressed as smaller instances of the same problem. Mastery for the Cambridge A‑Level exam requires:
With regular practice, students can confidently choose the most appropriate solution method and present it clearly in the exam.
Use this table to audit your lecture‑note packet against the Cambridge International AS & A Level Computer Science (9618) syllabus for 2026.
| Syllabus Area | What to Verify in the Notes | Typical Gaps & How to Fix Them |
|---|---|---|
| 1. Information Representation (binary, BCD, ASCII/Unicode, hex, two’s‑/one’s‑complement, overflow) | • All number‑base conversions are shown with worked examples. • Binary arithmetic (addition, subtraction) demonstrated step‑by‑step. • BCD and hexadecimal use‑cases explained. | Missing: concrete conversion tables, overflow illustration. Fix: add a short “conversion cheat‑sheet” and a worked 8‑bit two’s‑complement overflow example. |
| 2. Multimedia (Graphics & Sound) & Compression | • Bitmap vs. vector encoding, colour‑depth, resolution calculations. • Sampling‑rate & bit‑depth impact on audio file size. • Lossy vs. loss‑less methods (RLE, JPEG, MP3) with justification examples. | Missing: file‑size estimation formulae, real‑world justification (why choose JPEG for photos, PNG for icons). Fix: insert a quick calculation box and a “choose the right format” decision table. |
| 3. Communication & Networks | • LAN/WAN characteristics, client‑server vs. peer‑to‑peer, thin‑/thick‑client. • Topologies (bus, star, mesh, hybrid) with pros/cons. • IP addressing (IPv4/IPv6), subnetting, DNS, URL anatomy. • Ethernet/CSMA‑CD, wired vs. wireless, bit‑streaming concepts. | Missing: subnet mask example, DNS lookup flow, cloud‑computing overview. Fix: add a subnet‑mask worksheet and a short “cloud‑vs‑local” comparison graphic. |
| 4. Hardware & Processor Fundamentals | • CPU architecture (Von Neumann, registers, ALU, CU, clock, bus types). • Fetch‑Execute cycle diagram with register‑transfer notation. • Logic gates & truth tables, simple circuit design. • Assembly language basics (addressing modes, two‑pass assembler). • Bit‑manipulation (shifts, masks). | Missing: pipeline vs. non‑pipeline illustration, interrupt handling flow, example assembly program with comments. Fix: add a 5‑stage pipeline schematic and a short annotated assembly snippet (e.g., load‑add‑store). |
| 5. System Software | • OS roles (memory, file, process, device management) and utility examples. • Language translators (assembler, compiler, interpreter) with pros/cons. • IDE features (syntax checking, debugging). | Missing: explanation of dynamic linking (DLLs) and a simple compiler‑vs‑interpreter decision matrix. Fix: insert a “when to use a compiler vs. an interpreter” table. |
| 6. Security, Privacy & Data Integrity | • Threat types (malware, phishing, social engineering). • Countermeasures (encryption, hashing, digital signatures, firewalls). • Legal & ethical considerations (data protection, privacy laws). | Missing: real‑world case study and a checklist for secure coding practices. Fix: add a brief case study (e.g., password‑hash breach) and a “secure coding checklist” box. |
Run through this checklist after each topic to ensure full coverage and to spot any gaps before the exam.
Your generous donation helps us continue providing free Cambridge IGCSE & A-Level resources, past papers, syllabus notes, revision questions, and high-quality online tutoring to students across Kenya.