Iteration uses a loop to repeat a block of code; recursion solves a problem by having a function call itself on a simpler version of the same input. Both techniques can solve the same problems, but they differ in memory use, readability, and how naturally they fit different tasks.
What is the key structural difference?
Consider computing the factorial of n (n! = n × (n−1) × … × 1):
Iterative approach — a loop multiplies a running total:
def factorial_iterative(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
print(factorial_iterative(5)) # 120
Recursive approach — the function calls itself with a smaller input:
def factorial_recursive(n):
if n <= 1: # base case — stop recursion
return 1
return n * factorial_recursive(n - 1) # recursive case
print(factorial_recursive(5)) # 120
Both produce the same answer. The iterative version uses a loop; the recursive version uses the function call mechanism itself to "remember" where it was. Notice the recursive function has two essential parts: the base case (which stops the recursion) and the recursive case (which calls the function again with a simpler input).
How does the call stack differ between the two approaches?
When a function calls itself recursively, each call is placed on the call stack — a region of memory that stores the local variables and return address of every active function call.
Tracing factorial_recursive(4):
factorial_recursive(4) calls factorial_recursive(3)
factorial_recursive(3) calls factorial_recursive(2)
factorial_recursive(2) calls factorial_recursive(1)
factorial_recursive(1) returns 1 ← base case
factorial_recursive(2) returns 2 × 1 = 2
factorial_recursive(3) returns 3 × 2 = 6
factorial_recursive(4) returns 4 × 6 = 24
Each unresolved call occupies stack space. For n=1000, the stack holds 1000 unresolved calls simultaneously. If n is large enough, the stack overflows — a stack overflow error.
An iterative factorial uses O(1) memory (just the variables result and i) regardless of input size.
How do iteration and recursion compare overall?
| Criterion | Iteration | Recursion |
|---|---|---|
| Memory usage | O(1) — constant, loop variables only | O(depth) — each call uses stack space |
| Stack overflow risk | None | Yes, if recursion depth is too large |
| Speed | Usually faster (no function-call overhead) | Slightly slower (call overhead per step) |
| Readability for simple repetition | Clear and direct | More code for a simpler task |
| Readability for tree/divide-and-conquer | Awkward — needs an explicit stack | Natural and elegant |
| Ease of tracing | Straightforward | Requires tracing the call stack |
| Infinite loop risk | Yes, if termination condition is wrong | Yes, if base case is missing or wrong |
When is recursion the more natural choice?
Recursion shines when the problem is defined recursively — when it can be naturally split into a smaller version of itself:
Tree traversal — printing every item in a folder tree (folders contain files and other folders):
def print_tree(folder, indent=0):
print(" " * indent + folder.name)
for child in folder.children: # each child may also be a folder
print_tree(child, indent + 2) # recurse with same structure
Writing this iteratively requires an explicit stack to simulate what recursion handles automatically.
Merge sort and quicksort — both divide the list in half and recursively sort each half. The recursive form maps directly onto the algorithm's definition.
Mathematical sequences — the Fibonacci sequence (F(n) = F(n−1) + F(n−2)) and the Tower of Hanoi puzzle have definitions that are almost directly executable as recursive functions.
What must every correct recursive function have?
Two things are non-negotiable:
-
A base case — at least one input value for which the function returns a result without calling itself. Without a base case, recursion never terminates and the program crashes with a stack overflow.
-
Progress towards the base case — each recursive call must use a simpler or smaller input than the one before. If this is not guaranteed, the function might recurse infinitely even with a base case present.
# Correct — base case at n=0; each call reduces n by 1
def countdown(n):
if n == 0:
print("Blast off!")
else:
print(n)
countdown(n - 1)
# Incorrect — base case present but never reached
def broken(n):
if n == 0:
return 0
return broken(n + 1) # n increases, never reaches 0 — infinite recursion
Frequently asked questions
What is the main disadvantage of recursion compared with iteration?
The main disadvantage is memory consumption. Each recursive call occupies space on the call stack (local variables, return address). For deeply recursive problems — such as traversing a list of 10,000 elements recursively — the stack may overflow. Iteration uses constant memory regardless of the number of repetitions, making it safer and faster for problems where the number of steps is large.
Can every recursive algorithm be converted to an iterative one?
Yes, in principle. Any computation performed by a recursive function can also be performed by an iterative function, typically by managing an explicit stack data structure yourself. However, for naturally recursive problems (tree traversal, divide-and-conquer algorithms), the iterative version is often significantly more complex and harder to understand than the elegant recursive original.
What is a base case in recursion?
A base case is the condition under which a recursive function returns a result without making another recursive call. It is the stopping condition that prevents the function from calling itself forever. Without a base case (or with a base case that is never reached), the function recurses indefinitely until a stack overflow error terminates the program. Every correct recursive function must have at least one base case.
Which approach do GCSE examiners prefer — iteration or recursion?
Both are examined. You should be able to write iterative solutions (using for loops, while loops) and understand and trace recursive solutions. You should also be able to explain the differences: iteration uses less memory and is less prone to stack overflow; recursion is more elegant for problems with a naturally recursive structure. For exam questions asking you to write code, iteration is usually safer and more straightforward.
Trace both iterative and recursive solutions with Professor Turing at aitutors.me — step-by-step guidance through every call.