Recursion in C++: Structure With Examples
Learn how functions can call themselves to solve complex problems elegantly. Master the base case, recursive case, and call stack with practical examples.
- What recursion is and how it works in C++
- The concepts of base case and recursive case
- How to write recursive functions for common problems
- How the call stack works during recursion
- Common pitfalls and when to use recursion
1What is recursion?
Recursion is a programming technique where a function calls itself to solve a smaller version of the original problem.
In simpler terms: a function solves a problem by solving a smaller part of it repeatedly until it reaches a stopping condition.
2Structure of a recursive function
Every recursive function must have two essential parts:
- Base Case: A condition that ends the recursion (stops the function from calling itself forever)
- Recursive Case: The part where the function calls itself with a smaller or simpler version of the problem
General pattern:
returnType functionName(parameters) { if (base_case_condition) return base_value; else return functionName(smaller_problem); }
3Example 1: Factorial (n!)
The factorial of a number n is defined as: n! = n × (n-1) × (n-2) × ... × 1, and 0! = 1 (base case).
int factorial(int n) { if (n == 0) return 1; // base case else return n * factorial(n - 1); // recursive case }
Usage:
int main() { int n = 5; cout << "Factorial of " << n << " is " << factorial(n); return 0; }
4How recursion works: the call stack
When you call a recursive function, each call is placed on the call stack. Once the base case is reached, the calls start returning one by one, in reverse order.
For factorial(3):
-> 3 * factorial(2)
-> 2 * factorial(1)
-> 1 * factorial(0)
-> 1 (base case)
<- returns 1 * 1 = 1
<- returns 2 * 1 = 2
<- returns 3 * 2 = 6
5Example 2: Fibonacci sequence
The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, ...
fib(0) = 0fib(1) = 1fib(n) = fib(n-1) + fib(n-2)for n > 1
int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; return fib(n - 1) + fib(n - 2); }
cout << fib(7) << endl;
fib(5) calls fib(3) multiple times. We will discuss optimizations like memoization in later chapters.
6Example 3: Sum of digits
This function recursively calculates the sum of digits of a number. For n = 123, it returns 1 + 2 + 3 = 6.
int sumOfDigits(int n) { if (n == 0) return 0; return n % 10 + sumOfDigits(n / 10); }
cout << sumOfDigits(123) << endl;
7Example 4: Power function
Compute a^b (a raised to the power b) using recursion.
int power(int a, int b) { if (b == 0) return 1; return a * power(a, b - 1); }
cout << power(2, 5) << endl;
8Example 5: Tower of Hanoi
The Tower of Hanoi is a classic recursion problem. Move n disks from rod A to rod C using rod B as auxiliary.
void hanoi(int n, char source, char helper, char destination) { if (n == 1) { cout << "Move disk 1 from " << source << " to " << destination << endl; return; } hanoi(n - 1, source, destination, helper); cout << "Move disk " << n << " from " << source << " to " << destination << endl; hanoi(n - 1, helper, source, destination); }
hanoi(3, 'A', 'B', 'C');
9When should you use recursion?
- The problem can be broken into smaller, similar subproblems
- You can define a clear base case
- The problem involves tree traversal, divide-and-conquer, backtracking, or combinatorics
- The recursive solution is more elegant and readable than the iterative one
- The iterative solution is simpler and more efficient
- The recursion depth could be very large (risk of stack overflow)
- Performance is critical and recursion adds unnecessary overhead
10Common mistakes to avoid
11Mini exercises
- Write a recursive function to calculate the sum of the first n natural numbers.
- Create a recursive function to check if a string is a palindrome.
- Implement
gcd(a, b)using recursion (Hint: use Euclid's algorithm:gcd(a, b) = gcd(b, a % b)). - Use recursion to reverse an array in place.
Hint: For the palindrome check, compare the first and last characters, then recurse on the substring between them.
