Recursion: A Beginner's Guide to Solving Problems with Self-Referencing Functions.


Recursion is a fundamental concept in programming where a function calls itself to solve a problem. Think of it like breaking a big task into smaller, manageable parts. In this blog, we will explore how recursion works and how to use it in JavaScript.
What is Recursion?
Recursion is like opening a box to find another box inside, and so on, until you reach the smallest box. In programming, this means a function calling itself with a simpler version of the problem, repeating until the base case is reached.
How Does Recursion Work?
In recursion, every function needs:
A base case to stop the recursion.
A recursive case where the function calls itself with a simpler problem.
Simple Example (Factorial)
function factorial(n) {
if (n === 0) {
return 1; // Base case
} else {
return n * factorial(n - 1); // Recursive case
}
}
console.log(factorial(5)); // Output: 120
A step-by-step breakdown of the function calls:
factorial(5) => 5 * factorial(4)
factorial(4) => 4 * factorial(3)
factorial(3) => 3 * factorial(2)
factorial(2) => 2 * factorial(1)
factorial(1) => 1 * factorial(0)
factorial(0) => 1 (base case reached)
Visualizing Recursion: Detailed Data
To make recursion easier to understand, let's use visuals like flowcharts or stack diagrams. Here's a breakdown of how to represent recursion visually with a focus on the factorial example.
1. Flowchart Representation of Factorial Recursion
A flowchart can visually demonstrate how recursion works step by step. It shows the decision points and the flow of execution.
Factorial Function (Recursion Flowchart):
Start → Enter the number
n
(e.g.,n = 5
).Check if
n === 0
:If
yes
, return1
(base case).If
no
, move to the recursive call step.
Call
factorial(n - 1)
(recursive case).Multiply
n
by the result of the recursive call.Repeat until
n === 0
.End.
This flowchart illustrates how the function keeps calling itself with smaller values of n
until it hits the base case.
2. Stack Diagram for Factorial Recursion
The stack diagram helps in visualizing how function calls are stored in memory when a recursive function is executed. It tracks each function call as it is pushed onto the stack and how each function call is popped off as the recursion unwinds.
Here’s how a stack diagram would look for factorial(5)
:
Step 1:
factorial(5)
The function is called with
n = 5
.Since
n ≠ 0
, it callsfactorial(4)
.
Step 2:
factorial(4)
factorial(4)
callsfactorial(3)
becausen ≠ 0
.
Step 3:
factorial(3)
factorial(3)
callsfactorial(2)
.
Step 4:
factorial(2)
factorial(2)
callsfactorial(1)
.
Step 5:
factorial(1)
factorial(1)
callsfactorial(0)
.
Step 6:
factorial(0)
(Base Case)- Now that
n === 0
, the function returns1
.
- Now that
Now, the function calls start to "unwind" and pop off the stack:
Step 7: Return from
factorial(1)
factorial(1)
returns1 * 1 = 1
.
Step 8: Return from
factorial(2)
factorial(2)
returns2 * 1 = 2
.
Step 9: Return from
factorial(3)
factorial(3)
returns3 * 2 = 6
.
Step 10: Return from
factorial(4)
factorial(4)
returns4 * 6 = 24
.
Step 11: Return from
factorial(5)
factorial(5)
returns5 * 24 = 120
.
The final result, 120
, is returned and the stack is now empty.
3. Recursion Tree Diagram
A recursion tree is another way to represent how a recursive function operates. It shows how the function breaks down into smaller subproblems until it reaches the base case.
Here’s a recursion tree for factorial(5)
:
factorial(5)
|
-------------------------
| |
5 * factorial(4) return 1 (base case)
|
-----------------
| |
4 * factorial(3) return 1
|
-----------------
| |
3 * factorial(2) return 1
|
-----------------
| |
2 * factorial(1) return 1
|
-----------------
| |
1 * factorial(0) return 1
|
-----------------
| |
return 1 (base case)
Breakdown of Each Step:
factorial(5)
callsfactorial(4)
→ multiplies5 * factorial(4)
.factorial(4)
callsfactorial(3)
→ multiplies4 * factorial(3)
.factorial(3)
callsfactorial(2)
→ multiplies3 * factorial(2)
.factorial(2)
callsfactorial(1)
→ multiplies2 * factorial(1)
.factorial(1)
callsfactorial(0)
→ multiplies1 * factorial(0)
.factorial(0)
hits the base case and returns1
.
Now the function calls start to return:
factorial(1)
returns1 * 1 = 1
.factorial(2)
returns2 * 1 = 2
.factorial(3)
returns3 * 2 = 6
.factorial(4)
returns4 * 6 = 24
.factorial(5)
returns5 * 24 = 120
.
The result is 120
.
This should now be a clearer illustration of the recursive process with the factorial function!
Some Common Recursion Problems
Here are a few classic problems that are often solved using recursion. These problems will help reinforce how recursion can be applied in different scenarios:
Fibonacci Sequence
- The Fibonacci sequence is a series of numbers where each number is the sum of the two preceding ones. The sequence starts with
0
and1
. In recursion, you can break it down asfib(n) = fib(n-1) + fib(n-2)
.
- The Fibonacci sequence is a series of numbers where each number is the sum of the two preceding ones. The sequence starts with
Example in JavaScript:
function fibonacci(n) {
if (n <= 1) {
return n; // Base case
}
return fibonacci(n - 1) + fibonacci(n - 2); // Recursive case
}
console.log(fibonacci(5)); // Output: 5
- Sum of an Array
- To find the sum of an array using recursion, you reduce the problem by adding the first element to the sum of the remaining array.
Example in JavaScript:
function sumArray(arr) {
if (arr.length === 0) {
return 0; // Base case
}
return arr[0] + sumArray(arr.slice(1)); // Recursive case
}
console.log(sumArray([1, 2, 3, 4])); // Output: 10
- Tree Traversal
- Recursion is perfect for traversing trees (binary or general trees). For example, in a binary tree, you can use recursion to visit each node, either in pre-order, in-order, or post-order.
Things to Keep in Mind
While recursion is a powerful tool, there are a few important points to consider:
Base Case is Critical:
- Every recursive function needs a well-defined base case, which is the condition that ends the recursion. If the base case is not defined correctly, it can lead to infinite recursion, causing a stack overflow error.
Stack Overflow:
- Each recursive call consumes stack space. If recursion goes too deep (for example, when the problem size is too large or there are too many recursive calls), it can lead to a stack overflow error. This is why it's important to ensure the base case is hit and the recursion doesn't go on indefinitely.
Performance Considerations:
- Recursion can be inefficient in some cases, especially when there are overlapping subproblems. For example, in the Fibonacci sequence example above, many of the same values are recalculated multiple times. To optimize such cases, you can use memoization or dynamic programming.
Recursive Depth Limit:
- JavaScript, like many programming languages, has a default limit on recursion depth (the number of times a function can call itself). This limit can be adjusted in some environments, but it's generally a good practice to avoid deep recursion.
Conclusion
In conclusion, recursion is a fundamental technique in programming that allows you to solve complex problems by breaking them down into simpler subproblems. It's widely used in various algorithms, such as sorting, searching, dynamic programming, and mathematical problems like factorials, Fibonacci sequences, and tree traversal.
By understanding how recursion works and practicing with different problems, you can become proficient in using recursion to write elegant and efficient solutions to problems.
Remember:
Every recursive function must have a base case.
Be mindful of performance and stack overflow errors.
Practice recursion with a variety of problems to become comfortable with its application.
Now that you've learned the basics of recursion, I encourage you to try solving these problems on your own:
Implement a recursive solution to calculate the sum of an array.
Try solving a tree traversal problem, either in pre-order, in-order, or post-order.
Experiment with memoization to optimize recursive Fibonacci!
Feel free to share your solutions in the comments below, or reach out if you have any questions. Happy coding!
പൊളിക്ക് പിള്ളേരെ 💻😎
Subscribe to my newsletter
Read articles from Jayakrishnan m k directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jayakrishnan m k
Jayakrishnan m k
Dev