Lab 2 - Recursion - DATA STRUCTURE & ALGORITHMS
Lab 2 - Recursion - DATA STRUCTURE & ALGORITHMS
Lab 2
Recursion
In this lab session, we will explore recursion technique.
Instructions
Recursion is a common technique where a difficult problem is broken down into smaller instances
of the same problem. By applying the same procedure repeatedly, the problem becomes simpler
until reaching a base case that can be solved directly.
1. Basic Concepts
Definition: A function that is defined in terms of itself is called a recursive function.
A recursive function always has:
The following C/C++ implementation demonstrates how recursion can be used to compute the
Fibonacci sequence follows the mathematical definition above:
1 int fibo ( int n )
2 {
3 if ( n == 0)
4 return 0;
5 if ( n == 1)
6 return 1;
7 return fibo (n -1) + fibo (n -2) ; // Recursive call
8 }
2. Types of Recursion
A recursive function can be classified in many different ways based on the criteria of classification.
Below are common types of recursion:
• Indirect Recursion: A function calls another function, and that one calls back the original
one.
1 void A () {
2 B () ;
3 }
4
5 void B () {
6 A () ;
7 }
• Tail Recursion: The recursive call is the last operation in the function.
1 void tailRecursion ( int n ) {
2 if ( n == 0) return ;
3 cout << n << " " ;
4 tailRecursion ( n - 1) ;
5 }
• Non-Tail Recursion: There are computations or calls after the recursive call.
1 void nonTailRecursion ( int n ) {
2 if ( n == 0) return ;
3 nonTailRecursion ( n - 1) ;
4 cout << n << " " ;
5 }
Additionally, there are other classification methods, such as classification based on the way the
problem size is reduced (linear recursion, binary recursion, multiple recursion), or based on the
data structures used (recursion on linked lists, recursion on trees, recursion on graphs), etc.
For n = 10, the total recursive calls is 177 with many redundant calculations. Indeed, the number
of recursive calls grows exponentially in an exponential time complexity O(2n ).
The following code computes Fibonacci numbers using an iterative approach (removed recursion).
1 int fibo_iterative ( int n ) {
2 if ( n == 0) return 0;
3 if ( n == 1) return 1;
4 int calc_count = 0 , a = 0 , b = 1 , c ;
5 for ( int i = 2; i <= n ; i ++) {
6 c = a + b;
7 a = b;
8 b = c;
9 calc_count ++;
10 }
11 cout << " Total fibonacci calculating : " << calc_count << " \ n " ;
12 return b ;
13 }
The iterative approach only requires a loop of n−1 iterations, making it significantly more efficient
than recursion. The time complexity is O(n) and does not involve redundant calculations.
4. Memoization
A naive recursive implementation is inefficient due to redundant calculations, each call recomputes
the same values multiple times. Memoization is a technique that stores previously computed values
to avoid redundant computations.
The following C++ code demonstrates the Fibonacci function using memoization with an array
to store intermediate results.
1 # include < iostream >
2 using namespace std ;
3
15 int main ()
16 {
17 fill_n ( memo , MAX , -1) ; // Initialize memoization array
18 cout << " Fibonacci (5) : " << fibo (5) << endl ;
19 return 0;
20 }
With memoization technique, each Fibonacci number is computed only once and stored for reuse.
The time complexity is reduced to O(n) compared to the exponential complexity of naive recursion.
By reducing redundant calls, memoization significantly improves performance while retaining the
simplicity of recursion.
Exercises
Exercise 1. Factorial
Write a program to compute the factorial of a given non-negative integer n. The factorial of n is
defined as:
n! = n × (n − 1) × · · · × 1,
where 0! = 1.
Input:
Output:
• The factorial of n.
Example:
Input Output
5 120
0 1
Input:
Output:
Example:
Input Output
1234 10
9876 30
Input:
Output:
Example:
Input Output
24 18 6
100 75 25
Input:
Output:
• No otherwise.
Example:
Input Output
5 Yes
1 3 5 7 9
4 No
2 2 3 4
Input:
Output:
Example:
Input Output
hello olleh
world dlrow
Input:
Output:
• No otherwise.
Example:
Input Output
madam Yes
hello No
Input:
Output:
• A list of all possible permutations of the given set, each on a new line.
Example:
Input Output
3 1 2 3
1 2 3 1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Input:
Output:
Example:
Input Output
3 {}
1 2 3 {1}
{2}
{3}
{1,2}
{1,3}
{2,3}
{1,2,3}
Input:
Output:
Example:
Input Output
3 000
001
010
011
100
101
110
111
Input:
Output:
• Each solution should be represented as an n-length list, where the i-th number represents
the column position of the queen in row i.
Example:
Input Output
4 [2, 4, 1, 3]
[3, 1, 4, 2]
Regulations
Please follow these regulations:
• After completing assignment, check your submission before and after uploading to Moodle.
• You can use <vector> or any libraries that are not in the prohibited libraries listed above.
Your source code must be contributed in the form of a compressed file and named your submission
according to the format StudentID.zip. Here is a detail of the directory organization:
StudentID
Exercise_1.cpp
...
The end.