Quiz 2
Registry Synced

Recursion

977 words
5 min read

Reading compass

Now · 🎯 Learning Objectives

Recursion

Why read this? Some problems are naturally recursive — a problem contains a smaller version of itself. Think of Russian nesting dolls, or the definition of a directory: "a folder contains files and folders." Recursion is the programming technique of a function calling itself to solve such problems.

🎯 Learning Objectives

By the end of this topic, you will be able to:
  1. Understand recursion — a function calling itself
  2. Identify the base case (stopping condition) and recursive case
  3. Write recursive functions for factorial, Fibonacci, and more
  4. Trace recursive execution on the call stack
  5. Compare recursion vs iteration

📋 Prerequisites

  • Functions — Understanding how functions work.
  • While Loops — Understanding iterative solutions helps.

📖 Core Content

23.1 What Problem Does Recursion Solve?

Intuition: Imagine you're in a line and want to know your position. You ask the person ahead, "What's your number?" They ask the person ahead of them, and so on, until the front person says "I'm #1." Then each person adds 1 and passes it back. That's recursion — delegate to a smaller version of the same problem, then combine results.

23.2 Anatomy of a Recursive Function

Every recursive function has two parts:
  1. Base case — the simplest version, solved directly (no recursion)
  2. Recursive case — reduce the problem and call yourself
python
# runnable
def countdown(n):
    """Print numbers from n down to 1."""
    if n <= 0:          # Base case
        return
    print(n)            # Do something
    countdown(n - 1)    # Recursive case: call with smaller n
countdown(5)
Output:
pseudo
5
4
3
2
1

23.3 The Call Stack

Diagram Rendering diagram Each recursive call is placed on the call stack — like stacking plates. Python has a recursion limit (default ~1000). Too many recursive calls cause RecursionError.

23.4 Factorial with Recursion

n!=n×(n1)!n! = n \times (n-1)!
python
# runnable
def factorial(n):
    """Compute n! recursively."""
    if n <= 1:            # Base case: 0! = 1, 1! = 1
        return 1
    return n * factorial(n - 1)  # Recursive case
print(factorial(5))   # 120
print(factorial(10))  # 3628800
Trace for factorial(4):
pseudo
factorial(4) = 4 * factorial(3)
            = 4 * (3 * factorial(2))
            = 4 * (3 * (2 * factorial(1)))
            = 4 * (3 * (2 * 1))
            = 4 * (3 * 2)
            = 4 * 6
            = 24

23.5 Fibonacci with Recursion

Fn=Fn1+Fn2,F0=0,F1=1F_n = F_{n-1} + F_{n-2}, \quad F_0 = 0, F_1 = 1
python
# runnable
def fibonacci(n):
    """Return the nth Fibonacci number."""
    if n <= 1:          # Base case: F0 = 0, F1 = 1
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)  # Recursive case
for i in range(10):
    print(f"F{i} = {fibonacci(i)}")
Output:
pseudo
F0 = 0
F1 = 1
F2 = 1
F3 = 2
F4 = 3
F5 = 5
F6 = 8
F7 = 13
F8 = 21
F9 = 34

23.6 Worked Example 1: Sum of List (Recursive)

python
# runnable
def sum_list(lst):
    """Sum all elements in a list recursively."""
    if not lst:          # Base case: empty list
        return 0
    return lst[0] + sum_list(lst[1:])  # First + rest
print(sum_list([1, 2, 3, 4, 5]))  # 15

23.7 Worked Example 2: String Reversal (Recursive)

python
# runnable
def reverse_string(s):
    """Reverse a string recursively."""
    if len(s) <= 1:      # Base case: empty or single char
        return s
    return reverse_string(s[1:]) + s[0]  # Reverse rest, then add first
print(reverse_string("Python"))  # nohtyP

23.8 Worked Example 3: Power Function (Recursive)

python
# runnable
def power(base, exp):
    """Compute base^exp recursively."""
    if exp == 0:          # Base case: any number^0 = 1
        return 1
    return base * power(base, exp - 1)  # base * base^(exp-1)
print(power(2, 10))  # 1024
print(power(3, 4))   # 81

23.9 Worked Example 4: Palindrome Check (Recursive)

python
# runnable
def is_palindrome(s):
    """Check if string is palindrome recursively."""
    s = s.lower().replace(" ", "")
    if len(s) <= 1:
        return True
    if s[0] != s[-1]:
        return False
    return is_palindrome(s[1:-1])
print(is_palindrome("racecar"))   # True
print(is_palindrome("hello"))     # False
print(is_palindrome("A man a plan a canal panama"))  # True

23.10 Recursion vs Iteration

AspectRecursionIteration
CodeElegant, shortLonger, explicit
ReadabilityGood for tree structuresGood for linear tasks
MemoryMore (call stack)Less (no stack frames)
SpeedSlower (function call overhead)Faster
Infinite riskStack overflowInfinite loop
Best forTrees, fractals, divide-and-conquerSimple loops

⚠️ Common Pitfalls

Pitfall 1: Missing Base Case

The mistake: Recursive function without a base case — infinite recursion. Error: RecursionError: maximum recursion depth exceeded Fix: Always define a base case that stops the recursion.

Pitfall 2: Base Case Never Reached

The mistake: factorial(n): return n * factorial(n-1) with no base case for n=0. Fix: Add if n <= 1: return 1.

Pitfall 3: Exponential Recursion (Fibonacci)

The mistake: Recursive Fibonacci recalculates the same values repeatedly. fib(40) takes forever! Fix: Use memoization, iteration, or dynamic programming.

📝 Practice Questions

Q1: Trace factorial(3) step by step.
Answer:
pseudo
factorial(3) = 3 * factorial(2)
            = 3 * (2 * factorial(1))
            = 3 * (2 * 1)
            = 3 * 2
            = 6
Q2: Write a recursive function to compute the sum of digits of a number.
Answer:
python
def sum_digits(n):
    if n < 10:
        return n
    return n % 10 + sum_digits(n // 10)
print(sum_digits(1234))  # 10
Q3-10: Additional recursion questions.
(Following pattern.)

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.