Show understanding of recursion

Resources | Subject Notes | Computer Science

Recursion - A-Level Computer Science

Recursion

What is Recursion?

Recursion is a powerful programming technique where a function calls itself within its own definition. It's a way to solve problems by breaking them down into smaller, self-similar subproblems. A recursive function has a base case and a recursive step.

Key Concepts

  • Base Case: This is the condition that stops the recursion. Without a base case, the function would call itself infinitely, leading to a stack overflow.
  • Recursive Step: This is where the function calls itself with a modified input, moving closer to the base case.

How Recursion Works

When a recursive function is called, it's added to the call stack. The function continues to call itself, adding new frames to the stack. Each frame contains the function's local variables and the return address. When the base case is reached, the function returns a value. This value is then used by the previous call frame to calculate its own return value, and so on, until the initial call returns a final result.

Example: Factorial

A classic example of recursion is calculating the factorial of a non-negative integer. The factorial of n (denoted as n!) is the product of all positive integers less than or equal to n. For example, 5! = 5 * 4 * 3 * 2 * 1 = 120.

The factorial function can be defined recursively as follows:

  • Base Case: $0! = 1$
  • Recursive Step: $n! = n * (n-1)!$

Pseudocode for Factorial

Step Description Example (n=3)
1 Check if n is 0. If yes, return 1. n = 3, n is not 0
2 Otherwise, return n multiplied by the result of calling the factorial function with n-1. n = 3, return 3 * factorial(2)
3 The call factorial(2) will then execute the same process. factorial(2) returns 2 * factorial(1)
4 The call factorial(1) will then execute the same process. factorial(1) returns 1 * factorial(0)
5 The call factorial(0) will hit the base case and return 1. factorial(0) returns 1
6 The values are then returned back up the call stack. factorial(1) returns 1 * 1 = 1
7 factorial(2) returns 2 * 1 = 2
8 factorial(3) returns 3 * 2 = 6

Advantages of Recursion

  • Elegance and Readability: Recursive solutions can often be more concise and easier to understand than iterative solutions, especially for problems that are naturally recursive.
  • Natural Fit for Certain Problems: Some problems, like tree traversal and graph algorithms, are inherently recursive.

Disadvantages of Recursion

  • Overhead: Recursive calls involve function call overhead, which can be slower than iterative solutions.
  • Stack Overflow: If the recursion goes too deep (i.e., the base case is never reached), it can lead to a stack overflow error.

Tail Recursion

Tail recursion is a special form of recursion where the recursive call is the very last operation performed in the function. Some compilers can optimize tail-recursive functions into iterative code, eliminating the function call overhead and preventing stack overflow. However, not all languages or compilers support tail recursion optimization.

Example: Fibonacci Sequence (Recursive)

The Fibonacci sequence is a classic example often used to illustrate recursion. The sequence is defined as:

  • F(0) = 0
  • F(1) = 1
  • F(n) = F(n-1) + F(n-2) for n > 1

Here's a simple recursive implementation:

Suggested diagram: A tree showing the recursive calls for calculating F(4).

Iterative vs. Recursive

While recursion can be elegant, iterative solutions (using loops) are often more efficient in terms of memory usage and speed. The choice between recursion and iteration depends on the specific problem and the trade-offs between readability and performance.