Compose & Trace Recursive Algorithms (HL)

What Are Recursive Algorithms?

Recursion occurs when a function calls itself to solve a smaller version of a problem.

Every recursive algorithm needs a base case to stop further calls and avoid infinite loops.

Recursive Functions

How Recursive Algorithms Work

Each recursive function follows two parts:

  • Base Case: The simplest instance that returns a direct result (e.g. n == 0).
  • Recursive Case: The function calls itself with a smaller or simpler argument.

Example: Recursive Factorial Function

def factorial(n):
    if n == 0:
        return 1   # Base case
    return n * factorial(n - 1)   # Recursive case

print("Factorial:", factorial(5))
public class RecursionExample {
    public static int factorial(int n) {
        if (n == 0) return 1;   // Base case
        return n * factorial(n - 1);   // Recursive case
    }
    public static void main(String[] args) {
        System.out.println("Factorial: " + factorial(5));
    }
}

Tracing factorial(5)

How to Trace factorial(5)

  1. Recall the rule: factorial(n) = n × factorial(n−1) with base case factorial(1) = 1 (or factorial(0) = 1).
  2. Walk down the calls: record each call factorial(5)factorial(4)factorial(3)factorial(2)factorial(1).
  3. At the base case, return 1.
  4. Walk up the stack: for each waiting call, compute n × (return from below) and record that value.
  5. Continue until the original call returns 120.
Step Action n Return Value
1 Call factorial(5) 5
2 Call factorial(4) 4
3 Call factorial(3) 3
4 Call factorial(2) 2
5 Call factorial(1) 1
6 Call factorial(0) (base case) 0 1
7 Return from factorial(1): 1 × 1 1 1
8 Return from factorial(2): 2 × 1 2 2
9 Return from factorial(3): 3 × 2 3 6
10 Return from factorial(4): 4 × 6 4 24
11 Return from factorial(5): 5 × 24 5 120

Example: Sum of N Natural Numbers

def sum_n(n):
    if n == 0:
        return 0   # Base case
    return n + sum_n(n - 1)   # Recursive case

print("Sum:", sum_n(5))
public class RecursiveSum {
    public static int sumN(int n) {
        if (n == 0) return 0;        // Base case
        return n + sumN(n - 1);      // Recursive case
    }

    public static void main(String[] args) {
        System.out.println("Sum: " + sumN(5));
    }
}

Tracing sum_n(5)

How to Trace sum_n(5)

  1. Recall the rule: sum_n(n) = n + sum_n(n−1) with base case sum_n(0) = 0 (or sum_n(1) = 1).
  2. Walk down the calls: sum_n(5)sum_n(4)sum_n(3)sum_n(2)sum_n(1) → base.
  3. At the base, return 0.
  4. Walk up the stack: at each level compute n + (return from below) and update “Accumulated Sum” (e.g. 0 → 1 → 3 → 6 → 10 → 15).
  5. The original call returns 15.
Step Call n Return Accumulated Sum
1sum_n(5)5
2sum_n(4)4
3sum_n(3)3
4sum_n(2)2
5sum_n(1)1
6sum_n(0)000
7return from sum_n(1)11 + 0 = 11
8return from sum_n(2)22 + 1 = 33
9return from sum_n(3)33 + 3 = 66
10return from sum_n(4)44 + 6 = 1010
11return from sum_n(5)55 + 10 = 1515

Avoiding Common Errors

  • Missing Base Case: Always define and test the simplest case (eg n == 0), or risk infinite recursion.
  • Excessive Calls: Cache results when possible (memoisation) to avoid redundant work.
  • Stack Overflow: Keep recursion depth reasonable or convert to iterative solutions when you hit limits.

 Key Takeaways

  • Recursive algorithms call themselves on a smaller input until a base case is reached.
  • Tracing helps visualise the call stack and return values step by step.
  • Simple recursive patterns include factorial and sum of natural numbers.
  • Recursion can simplify code but requires care to avoid memory and performance issues.