0% found this document useful (0 votes)
4 views10 pages

Lab 2 - Recursion

This document is a lab session guide on recursion, covering its basic concepts, types, and implementations in C/C++. It explains the inefficiencies of naive recursion and introduces techniques such as iteration and memoization to improve performance. Additionally, it provides exercises for students to practice recursion through various programming tasks.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views10 pages

Lab 2 - Recursion

This document is a lab session guide on recursion, covering its basic concepts, types, and implementations in C/C++. It explains the inefficiencies of naive recursion and introduces techniques such as iteration and memoization to improve performance. Additionally, it provides exercises for students to practice recursion through various programming tasks.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Recursion Data structures and Algorithms CSC10004

Weekly Lab

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:

• Base Case: Defines the termination condition.

• Recursive Case: The function is redefined in a smaller scope.

For example, the Fibonacci sequence is defined as:







0, if n = 0

f (n) = 1, if n = 1 (1)



f (n − 1) + f (n − 2),

if n ≥ 2

Therefore, the Fibonacci sequence is as follows: 0, 1, 1, 2, 3, 5, 8, etc.

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 }

VNU-HCMUS Department of Computer Science, FIT Page 1


Recursion Data structures and Algorithms CSC10004

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:

Recursion Call Type


• Direct Recursion: A function calls itself within its body.
1 void func () {
2 func () ; // Calls itself
3 }

• 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 and Non-Tail Recursion

• 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.

VNU-HCMUS Department of Computer Science, FIT Page 2


Recursion Data structures and Algorithms CSC10004

3. Removing Recursion (Iteration)


A naive recursive implementation is inefficient due to redundant calculations. The C/C++ code
below implements a recursive Fibonacci function with a call counter.
1 int call_count ; // Counter for recursive calls
2 int fibo ( int n ) {
3 call_count ++; // Add this line
4 ... // Same as above implementation
5 }
6 // In the main function
7 call_count = 0;
8 int result = fibo (10) ;
9 cout << " Total recursive calls : " << call_count << " \ n " ;

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.

n Recursive Calls O(2n ) Iterative Loops O(n)


5 15 3
10 177 9
20 21,891 19
30 2,692,537 29

Table 1: Comparison of recursive and iterative Fibonacci computations.

VNU-HCMUS Department of Computer Science, FIT Page 3


Recursion Data structures and Algorithms CSC10004

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

4 const int MAX = 100;


5 int memo [ MAX ];
6

7 int fibo ( int n )


8 {
9 if ( n == 0) return 0;
10 if ( n == 1) return 1;
11 if ( memo [ n ] != -1) return memo [ n ]; // Check if already computed
12 return memo [ n ] = fibo (n -1) + fibo (n -2) ;
13 }
14

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.

n Recursive Calls O(2n ) Memoized Calls O(n)


5 15 5
10 177 10
20 21,891 20
30 2,692,537 30

Table 2: Comparison of naive recursion and memoization in Fibonacci computation.

By reducing redundant calls, memoization significantly improves performance while retaining the
simplicity of recursion.

VNU-HCMUS Department of Computer Science, FIT Page 4


Recursion Data structures and Algorithms CSC10004

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:

• A non-negative integer n (0 ≤ n ≤ 20).

Output:

• The factorial of n.

Example:

Input Output
5 120
0 1

Exercise 2. Sum of Digits


Write a program to compute the sum of the digits of a given positive integer.

Input:

• A positive integer n (1 ≤ n ≤ 1018 ).

Output:

• The sum of the digits of n.

Example:

Input Output
1234 10
9876 30

VNU-HCMUS Department of Computer Science, FIT Page 5


Recursion Data structures and Algorithms CSC10004

Exercise 3. Greatest Common Divisor


Write a program to compute the greatest common divisor (GCD) of two integers a and b.

Input:

• Two positive integers a and b (1 ≤ a, b ≤ 1018 ).

Output:

• The greatest common divisor of a and b.

Example:

Input Output
24 18 6
100 75 25

Exercise 4. Check Strictly Increasing Array


Write a program to determine whether a given array of integers is strictly increasing.

Input:

• An integer n (1 ≤ n ≤ 104 ), the number of elements in the array.

• A sequence of n integers (−106 ≤ ai ≤ 106 ).

Output:

• Yes if the array is strictly increasing.

• No otherwise.

Example:

Input Output
5 Yes
1 3 5 7 9
4 No
2 2 3 4

VNU-HCMUS Department of Computer Science, FIT Page 6


Recursion Data structures and Algorithms CSC10004

Exercise 5. Reverse a String


Write a program to reverse a given string.

Input:

• A string s consisting of only lowercase or uppercase characters where 1 ≤ |s| ≤ 106 .

Output:

• The reversed string.

Example:

Input Output
hello olleh
world dlrow

Exercise 6. Check Palindrome String


Write a program to check whether a given string is a palindrome. A palindrome is a string that
reads the same backward as forward.

Input:

• A string s consisting of lowercase characters only where 1 ≤ |s| ≤ 106 .

Output:

• Yes if the string is a palindrome.

• No otherwise.

Example:

Input Output
madam Yes
hello No

VNU-HCMUS Department of Computer Science, FIT Page 7


Recursion Data structures and Algorithms CSC10004

Exercise 7. Generate Permutations


Write a program to generate all permutations of a given set of distinct integers.

Input:

• An integer n (1 ≤ n ≤ 10) representing the number of elements in the set.

• A sequence of n distinct integers ai where |ai | ≤ 109 .

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

Exercise 8. Generate Subsets


Write a program to generate all subsets of a given set of distinct integers.

Input:

• An integer n (1 ≤ n ≤ 10) representing the number of elements in the set.

• A sequence of n distinct integers ai where |ai | ≤ 109

Output:

• A list of all possible subsets, each on a new line.

VNU-HCMUS Department of Computer Science, FIT Page 8


Recursion Data structures and Algorithms CSC10004

Example:

Input Output
3 {}
1 2 3 {1}
{2}
{3}
{1,2}
{1,3}
{2,3}
{1,2,3}

Exercise 9. Generate Binary Strings


Write a program to generate all binary strings of length n.

Input:

• An integer n (1 ≤ n ≤ 10) representing the length of the binary string.

Output:

• A list of all possible binary strings of length n, each on a new line.

Example:

Input Output
3 000
001
010
011
100
101
110
111

VNU-HCMUS Department of Computer Science, FIT Page 9


Recursion Data structures and Algorithms CSC10004

Exercise 10. N-Queens Problem


Write a program to solve the N-Queens problem, which places n queens on an n × n chessboard
such that no two queens attack each other.

Input:

• An integer n (1 ≤ n ≤ 10) representing the size of the chessboard.

Output:

• A list of all possible valid solutions.

• 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:

• You are allowed to use any IDE.

• After completing assignment, check your submission before and after uploading to Moodle.

• Prohibited libraries: <set>, <unordered_set>, <map>, <unordered_map>, <algorithm>, and


<bits/stdc++.h>.

• You can use <vector> or any libraries that are not in the prohibited libraries listed above.

Your source code must be submitted in the form of a compressed ZIP file and it should be named
according to the format StudentID.zip. Here is the required directory organization:
StudentID
Exercise_1.cpp
...

The end.

VNU-HCMUS Department of Computer Science, FIT Page 10

You might also like