week02_Recursion
week02_Recursion
and algorithms
CONTENT
• Basic definition
• Memorized recursion
ALGORITHMS
WEEK 2: RECURSION, MEMORIZED
RECURSION
3 4
BASIC DEFINITION BASIC DEFINITION
• Recursive object: defined through itself but on a smaller scale • Recursive object: defined through itself but on a smaller scale
• Basic step: Determine the value of a function with some initial parameter values • Basic step: determine the first elements of the set
• Recursive step: Determine the relationship between the function depending on the same • Recursive step: determine the rule indicating that larger word parts belong to the set of original
function but with smaller parameters elements
• Recursion: F(n) = F(n-1) + n, • Recursion: C(k, n) = C(k-1,n-1) + C(k,n-1), for others • Recursion: If x and y belong to S then x + y
with n > 1 belongs to S
5 6
A recursive algorithm is an algorithm that calls itself with a smaller input size.
Recursive(input) {
Recursive algorithms are often used when needing to deal with recursively defined objects. if (size of input is minimum) then
Example: The recursive definition of a Fibonacci sequence: Do basic steps; /* Solve the problem with the smallest size*/
else {
• f(0) = 0, f(1) = 1, Recursive(input with smaller size); /* Recursive step for
subproblems*/
• f(n) = f(n-1) + f(n-2) with n > 1 /* Note: There might exist other recursive calls*/
High-level programming languages often allow the construction of recursive functions, meaning Combine results of subproblems to get solution;
that the body of the function contains calls to itself. Therefore, when implementing recursive return solution;
}
algorithms, people often build recursive functions.
}
7 8
EXAMPLE EXAMPLE
Example 1: Calculate n! with the recursive formulation: int factorial(int n){ Example 2: Calculate the Fibonacci sequence:
f(0) = 1 if (n==0)
f(n) = n * f(n-1) return 1;
F(0) =0; F(1) = 1
(7) return 6 else
return n*factorial(n-1); F(n) = F(n-1) + F(n-2) với n ≥ 2
factorial(3): }
3 == 0 ? NO
return 3*factorial(2) (1) In factorial(3) int F(int n){
Call factorial(2)
The execution of factorial(3) will stop when if (n < 2)
(6) return 2 factorial(2): factorial(2) returns a result
return n;
2 == 0 ? NO
(2) In factorial(2) else
return 2*factorial(1)
Call factorial(1) When factorial(2) return a result, return F(n-1) + F(n-2);
(5) return 1
factorial(3) continues executing. }
factorial(1):
1 == 0 ? NO (3) In factorial(1)
return 1*factorial(0)
Call factorial(0)
(4) return 1
factorial(0):
0 == 0 ? YES
return 1
9 10
Example 3: Hanoi Tower: Moving n disks from pile a to pile c using pile b as an intermediary: HanoiTower(n, a, c, b);
Disc movement consists of 3 stages:
The Tower of Hanoi problem is presented as follows: “There are 3 piles a, b, c. On pile a there is a (1) Move n-1 disks from pile a to pile b, using pile c as an intermediary
stack of n disks, the diameter decreasing from bottom to top. It is necessary to move the stack of
disks from pile a to pile c following the rules: (2) Move 1 disk (the disk with the largest diameter) from pile a to pile c
• Only transfer 1 disk at a time (3) Move n-1 disks from pile b to pile c, using pile a as an intermediary
• Only discs with smaller diameters should be placed on top of disk with larger diameters. During
the transfer process, it is allowed to use pile b as an intermediate pile.
The problem is: List the steps to move the disks that need to be performed to complete the task set
out in the problem.
11 12
EXAMPLE: HANOI TOWER EXAMPLE: HANOI TOWER
Moving n disks from pile a to pile c using pile b as an intermediary: HanoiTower(n, a, c, b); The algorithm can be described in the following recursive procedure:
Disc movement consists of 3 stages: HanoiTower(n, a, c, b) {//Move n-1 disks from pile a to pile b, using pile c as an intermediary
(1) Move n-1 disks from pile a to pile b, using pile c as an intermediary if (n==1) then <move a disk from pile a to pile c>
Solve a problem of size n-1: HanoiTower(n-1,a,b,c)
else {
(2) Move 1 disk (the disc with the largest diameter) from pile a to pile c
Solve a problem of size 1: HanoiTower(1,a,c,b) HanoiTower(n-1,a,b,c);
(3) Move n-1 disks from pile b to pile c, using pile a as an intermediary HanoiTower(1,a,c,b);
Solve a problem of size n-1: HanoiTower(n-1,b,c,a)
HanoiTower(n-1,b,c,a);
}
}
Disc movement consists of 3 stages:
(1) Move n-1 disks from pile a to pile b, using pile c as an intermediary
(2) Move 1 disk (the disk with the largest diameter) from pile a to pile c
(3) Move n-1 disks from pile b to pile c, using pile a as an intermediary
Pile a Pile c Pile b
13 14
#include<stdio.h>
To analyze recursive algorithms, we usually proceed as follows:
int i = 0;
void HanoiTower(int n, char source, char target, char inter) Let T(n) be the algorithm's calculation time
{
if(n==1){ Build a recursive formula for T(n)
printf("Move a disk from pile %c to pile %c\n", source,
target); Solve the resulting recursive formula to give an estimate for T(n)
i++;
return;
} else{
HanoiTower(n-1, source, inter, target);
HanoiTower(1, source, target, inter); In general, we only need a close estimate of the growth rate of T(n), so solving the recursive
}
HanoiTower(n-1, inter, target, source);
formula for T(n) is to give an estimate of the growth rate of T(n) in asymptotic notation.
}
int main()
{
int n;
printf("Enter the number of disks n = "); scanf("%d", &n);
HanoiTower(n, 'a', 'c', 'b');
printf("The total number of steps to move disks = %d", i);
return 0;
}
15 16
ANALYZE RECURSIVE ALGORITHMS ANALYZE RECURSIVE ALGORITHMS
Example: Calculate n! with the recursive formula: int factorial(int n){ Example: Calculate n! with the recursive formula: int factorial(int n){
if (n==0) if (n==0)
f(0) = 1 return 1; f(0) = 1 return 1;
f(n) = n * f(n-1) else f(n) = n * f(n-1) else
return n*factorial(n-1); return n*factorial(n-1);
} }
Let T(n) be the number of multiplication operations that must be performed in the call to factorial(n). Let T(n) be the number of multiplication operations that must be performed in the call to factorial(n).
We have: We have:
T(0) = 0, T(0) = 0,
T(n) = T(n-1) +1, n≥1 T(n) = T(n-1) +1, n≥1
17 18
Let T(n) be the number of multiplication operations that must be performed in the call to int F(int n){
• Duplicate subproblems if (n < 2) return n;
factorial(n). We have:
Example 1: Calculate the Fibonacci sequence : else return F(n-1) + F(n-2);
T(0) = 0,
}
T(n) = T(n-1) +1, n≥1 F(0) =0; F(1) = 1
Solving the recursive formula T(n), we have: F(n) = F(n-1) + F(n-2) với n ≥ 2
• Duplicate subproblems int C(int k, int n){ In the two examples above, we have seen that the recursive algorithms for calculating Fibonacci
if (k == 0|| k == n)return 1; numbers and calculating binomial coefficients are inefficient.
Example 2: Calculate the binomial else return C(k-1,n-1)+C(k,n-1);
} To increase the efficiency of recursive algorithms, we can use memorized recursion techniques.
coefficient:
Using memorized recursion techniques, in many cases, we can preserve the recursive structure
C(0,n) = 1, C(n,n) =1; for all n ≥ 0, of the algorithm and at the same time ensure its efficiency. The biggest disadvantage of this
approach is the memory requirement.
C(k,n) = C(k-1,n-1)+C(k,n-1), 0 < k < n
21 22
THANK YOU !
int C(int k, int n) {
if (k == 0 || k == n) M[k][n] = 1;
Non-memorized recursion else {
int C(int k, int n){ if(M[k][n] == 0) M[k][n] = C(k-1,n-1) + C(k,n-1);
if (k == 0 || k == n)
return 1; }
else return M[k][n];
return C(k-1,n-1) + C(k,n-1);
} }
Before calling the function C(k, n), call the init() function
to initialize the elements in the array M[ ][ ] = 0
25 26