Recursion in Data Structures
Recursion in Data Structures
You might have already come across recursion while learning Recursion in C and Recursion in
C++. We even saw in the second tutorial, Data Structures and Algorithms, that recursion is a
problem-solving technique in which a function calls itself.
In this DSA tutorial, we will see the recursion in detail i.e. its features, working, implementation, etc.
To further enhance your understanding and application of recursion, consider enrolling in the Best
Data Structures and Algorithms Course, to gain comprehensive insights into effective data
structure utilization for improved problem-solving and time management.
Recursion is the process in which a function calls itself again and again. It entails decomposing a
challenging issue into more manageable issues and then solving each one again. There must be a
terminating condition to stop such recursive calls. Recursion may also be called the alternative to
iteration. Recursion provides us with an elegant way to solve complex problems, by breaking them
down into smaller problems and with fewer lines of code than iteration.
Recursive Function
A recursive function is a function that calls itself one or more times within its body. A recursive
function solves a particular problem by calling a copy of itself and solving smaller subproblems of the
original problems. Many more recursive calls can be generated as and when required. It is
necessary to have a terminating condition or a base case in recursion, otherwise, these calls may go
endlessly leading to an infinite loop of recursive calls and call stack overflow.
The recursive function uses the LIFO (LAST IN FIRST OUT) structure just like the stack data
structure. A recursion tree is a diagram of the function calls connected by pointed(up or down)
arrows to depict the order in which the calls were made.
1. A base case, in which the recursion can terminate and return the result immediately.
2. A recursive case, in which the function is supposed to call itself, to break the current
problem down into smaller problems.
Similarly, the input size gets smaller and smaller with each recursive call, and we get the solution to
that smaller problem. Later, we combine those results to find the solution to the entire problem.
144
Properties of Recursion
1. It solves a problem by breaking it down into smaller sub-problems, each of which can be
solved in the same way.
2. A recursive function must have a base case or stopping criteria to avoid infinite recursion.
3. Recursion involves calling the same function within itself, which leads to a call stack.
4. Recursive functions may be less efficient than iterative solutions in terms of memory and
performance.
Applications of Recursion
1. Recursive solutions are best suited to some problems like:
1. Tree Traversals: InOrder, PreOrder, PostOrder
2. Graph Traversals: DFS [Depth First Search] and BFS [Breadth First Search]
3. Tower of Hanoi
4. Backtracking Algorithms
5. Divide and Conquer Algorithms
6. Dynamic Programming Problems
7. Merge Sort, Quick Sort
8. Binary Search
9. Fibonacci Series, Factorial, etc.
2. Recursion is used in the design of compilers to parse and analyze programming languages.
3. Many computer graphics algorithms, such as fractals and the Mandelbrot set, use recursion
to generate complex patterns.
Advantages of Recursion
1. Clarity and simplicity: Recursion can make code more readable and easier to understand.
Recursive functions can be easier to read than iterative functions when solving certain types
of problems, such as those that involve tree or graph structures.
2. Reducing code duplication: Recursive functions can help reduce code duplication by
allowing a function to be defined once and called multiple times with different parameters.
3. Solving complex problems: Recursion can be a powerful technique for solving complex
problems, particularly those that involve dividing a problem into smaller subproblems.
4. Flexibility: Recursive functions can be more flexible than iterative functions because they
can handle inputs of varying sizes without needing to know the exact number of iterations
required.
What is Recursion?
The process in which a function calls itself directly or indirectly is called recursion
and the corresponding function is called a recursive function. Using a recursive
algorithm, certain problems can be solved quite easily. Examples of such problems
are Towers of Hanoi (TOH), Inorder/Preorder/Postorder Tree Traversals , DFS of
Graph, etc. A recursive function solves a particular problem by calling itself with
different parameters to solve smaller subproblems of the original problem. The
called function may further call itself and this process might continue forever. So it
is essential to know that we should provide a certain case in order to terminate this
recursion process. We can say that every time the function calls itself with a
simpler version of the original problem and moves toward the termination case or
base case.
Need of Recursion
Recursion is an amazing technique with the help of which we can reduce the
length of our code and make it easier to read and write. It has certain advantages
over the iteration technique which will be discussed later. A task that can be
defined with its similar subtask, recursion is one of the best solutions for it. For
example; The Factorial of a number.
Properties of Recursion:
Performing the same operations multiple times with different inputs.
In every step, we try smaller inputs to make the problem smaller.
Base condition is needed to stop the recursion otherwise infinite loop will occur.
Algorithm: Steps
Step1 – Define a base case: Identify the simplest case for which the solution is
known or trivial. This is the stopping condition for the recursion, as it prevents the
function from infinitely calling itself.
Step3 – Ensure the recursion terminates: Make sure that the recursive function
eventually reaches the base case, and does not enter an infinite loop.
step4 – Combine the solutions: Combine the solutions of the subproblems to solve
the original problem.
A Mathematical Interpretation
Let us consider a problem that a programmer has to determine the sum of first n
natural numbers, there are several ways of doing that but the simplest approach is
simply to add the numbers starting from 1 to n. So the function simply looks like
this,
approach(1) – Simply adding one by one
f(n) = 1 + 2 + 3 +……..+ n
but there is another mathematical approach of representing this,
approach(2) – Recursive adding
f(n) = 1 n=1
f(n) = n + f(n-1) n>1
There is a simple difference between the approach (1) and approach(2) and that is
in approach(2) the function “ f( ) ” itself is being called inside the function, so this
phenomenon is named recursion, and the function containing recursion is called
recursive function, at the end, this is a great tool in the hand of the programmers to
code some problems in a lot easier and efficient way.
How are recursive functions stored in memory?
Recursion uses more memory, because the recursive function adds to the stack
with each recursive call, and keeps the values there until the call is finished. The
recursive function uses LIFO (LAST IN FIRST OUT) Structure just like the stack
data structure. https://www.geeksforgeeks.org/stack-data-structure/
C++CJavaPythonC#JavaScriptPHP
#include <stdio.h>
int fact(int n) {
// BASE CONDITION
if (n == 0 || n == 1)
return 1;
int main() {
return 0;
In the above example, the base case for n < = 1 is defined and the larger value of
a number can be solved by converting to a smaller one till the base case is
reached.
How a particular problem is solved using recursion?
The idea is to represent a problem in terms of one or more smaller problems, and
add one or more base conditions that stop the recursion. For example, we compute
factorial n if we know the factorial of (n-1). The base case for factorial would be n =
0. We return 1 when n = 0.
Why Stack Overflow error occurs in recursion?
If the base case is not reached or not defined, then the stack overflow problem
may arise. Let us take an example to understand this.
int fact(int n)
{
// wrong base case (it may cause
// stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
If fact(10) is called, it will call fact(9), fact(8), fact(7), and so on but the number will
never reach 100. So, the base case is not reached. If the memory is exhausted by
these functions on the stack, it will cause a stack overflow error.
What is the difference between direct and indirect recursion?
A function fun is called direct recursive if it calls the same function fun. A function
fun is called indirect recursive if it calls another function say fun_new and fun_new
calls fun directly or indirectly. The difference between direct and indirect recursion
has been illustrated in Table 1.
// An example of direct recursion
void directRecFun()
{
// Some code....
directRecFun();
// Some code...
}
indirectRecFun2();
// Some code...
}
void indirectRecFun2()
{
// Some code...
indirectRecFun1();
// Some code...
}