0% found this document useful (0 votes)
36 views

USTH Algorithm Recursion

Recursion algorithms were discussed. Key points include: - Recursion involves dividing a problem into smaller subproblems and solving those subproblems recursively until they are simple enough to solve directly. - Examples like the Tower of Hanoi puzzle and calculating factorials demonstrate how recursion works by reducing problems into smaller instances of the same problem. - Recursive algorithms must have a base case where the problem is simple enough to solve without further recursion, otherwise the algorithm would recurse indefinitely.

Uploaded by

nhng2421
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

USTH Algorithm Recursion

Recursion algorithms were discussed. Key points include: - Recursion involves dividing a problem into smaller subproblems and solving those subproblems recursively until they are simple enough to solve directly. - Examples like the Tower of Hanoi puzzle and calculating factorials demonstrate how recursion works by reducing problems into smaller instances of the same problem. - Recursive algorithms must have a base case where the problem is simple enough to solve without further recursion, otherwise the algorithm would recurse indefinitely.

Uploaded by

nhng2421
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 73

Recursion algorithms

Suggestion for students for this section


- You are able to program with any language, such as Pascal,
C, C++, Java.... and you did learn "function call" method
- You will study with your computer in which a familiar
programming software is installed
Recursion Algorithm
Subject: Introduction to Algorithm • Simplify and delegate
Lecturer: Hoang Do Thanh Tung • Tower of Hanoi puzzle
Credit points 3 ECTS • Recursion Algorithm
Level Undergraduate
Teaching time 2021 • Exercises
Location University of Science and Technology of Hanoi
• Practice
Simplify and delegate
Reduction to simplify a problem

 Reduction is the single most common technique used in designing algorithms


 Reducing one problem X to another problem Y (or set of problems) means
 to write an algorithm for X, using an algorithm for Y as a subroutine or black box.
Recursion to delegate a problem to subs
 Recursion is a particularly powerful kind of reduction,
 Recursion can be defined loosely as follows:
 If the given problem is small or simple enough, just solve it. Otherwise,
 Reduce the problem to one or more simpler instances of the same problem and
‘simpler’ and ‘simpler’ subproblems

 Correctness of a Recursive algorithm is that it must stop and never recurses


forever
 It needs a finiteness condition when simplification is either unnecessary or impossible for
a subproblem
Clean the house
Clean the house
Clean the house

Clean the Clean the house


house and Clean the house
don’t ask
anyone else
If you are confused how it works, ..

 Method of thinking:
 Imagine that someone else is going to solve the simpler problems
 Your only task is to simplify the original problem, and
 The Recursion Fairy will magically take care of the simpler subproblems

Clean the house


Clean the house

Clean and Clean the house


don’t ask Clean the house
anyone else
Tower of Hanoi puzzle
Remarkable story
 The Tower of Hanoi puzzle was first published by the mathematician François
Éduoard Anatole Lucas in 1883,
• In the great temple, there were fixed three diamond needles.

• On one of these needles, at the creation,


• God placed 64 discs of pure gold,
• the discs is smaller and smaller up to the top one.
• The priests transfer the discs from one needle to another according to laws,
• must not move more than one disc at a time, and
• must place this disc on a needle so that there is no smaller disc below it.
• When the 64 discs are moved to another needle is time the world will vanish
Towers of Hanoi
 Task: Move n disks from current post to another post.

Post 1 Post 2 Post 3

 Rules:
 (1) Can only move one disk at a time.
 (2) A larger disk can never be placed on top of a
smaller disk.
(3) May use third post for temporary storage.
Solution for n = 2

1 2 3
How is about n>2 ?

 Suppose disks start on Post 1, and target is Post 3.

 1. Move top n-1 disks to


Post 2. 1 2 3

 2. Move largest disk to


Post 3.
1 2 3

 3. Move n-1 disks from


Post 2 to Post 3.

1 2
17-11 3
Task Decomposition (cont.)

 Task 1 is really the same problem,


with fewer disks and a different target post.
 "Move n-1 disks from Post 1 to Post 2."

 And Task 3 is also the same problem,


with fewer disks and different starting and target posts.
 "Move n-1 disks from Post 2 to Post 3."

 So this is a recursive algorithm.


 The terminal case is moving the smallest disk -- can move
directly without using third post.
 Number disks from 1 (smallest) to n (largest).
Algorithm for n = 6
1. If n = 1:
1.1. Move a single disk from source to dest.
2. If n > 1:
2.1. Let spare be the remaining pole, other than source and dest.
2.2. Move a tower of (n–1) disks from source to spare.
2.3. Move a single disk from source to dest.
2.4. Move a tower of (n–1) disks from spare to dest.
3. Terminate.

source dest spare 2-13


Towers of Hanoi: Pseudocode
 MoveDisk(diskNumber, startPost, endPost, midPost)
{
if (diskNumber > 1) {
/* Move top n-1 disks to mid post */
MoveDisk(diskNumber-1, startPost, midPost, endPost);
printf("Move disk number %d from %d to %d.\n",
diskNumber, startPost, endPost);
/* Move n-1 disks from mid post to end post */
MoveDisk(diskNumber-1, midPost, endPost, startPost);
}
else
 Move 1 disk from startPost to endPost;
printf("Move disk number 1 from %d to %d.\n",
startPost, endPost);
}
Analyse the algorithm

 Analysis (counting moves):


Let the total no. of moves required to move a tower of n disks be moves(n).
Then:
moves(n) = 1 if n = 1
moves(n) = 1 + 2*moves(n–1) if n > 1
Solution:
moves(n) = 2n – 1
Time complexity is O(2n).
Tree of calls for the Tower of Hanoi Puzzle
n

n-1 n-1

n-2 n-2 n-2 n-2


... ... ...
2 2 2 2

1 1 1 1 1 1 1 1
When will the world vanish?

 Moving a tower of 64 disks


requires 264 − 1 = 18,446,744,073,709,551,615 individual moves
 Impressive rate of one move per second, the monks will be at work for
approximately 585 billion years
Recursion algorithm
Divide and Conquer
Recursion

 a special divide and conquer problem solving technique

 Wait for someone else to solve the problem of size n − 1, size n −


2, etc...

 When you receive the solution for the problem of size n − 1, size n
− 2, etc..., you will then use these solutions to solve
the original problem.
Recursive problem

 Recursive problem = a problem that is defined with one or


more smaller problems of the same kind

 Example: the factorial of the number n


Example

 Now, suppose that you know (e.g., someone told you) that:

 Then, we can solve the original problem (10!) very easily:


The Recursive Property

A problem X(n) has the recursive property if:

 The problem X(n) can be solved using the solution of one or


more smaller problems X(n−1), X(n−2), ...

 A sufficient number of base (simple) cases of the problem can


be solved readily.
Example

The problem factorial(n) can be solved using the


solution of one smaller problem factorial(n−1)

Because one smaller problem is used to solve factorial(n), we


need one base case
The base (simple) case n = 0 of the factorial problem can
be solved readily:
Design Algorithm for a recursive problem

1. Find out which smaller problems you need to use to solve


the original problem

2. Find out how to use the solutions of the smaller


problems to solve the original problem.

3. Find the solutions for a sufficient number of the base cases.


Computing n!

 Which smaller problem do we use to solve factorial(n):

 How do we use the solution sol1 to solve factorial(n):

 Because we used factorial(n−1), we will need the solution for 1 base case:
Computing n! algorithm
int factorial( int n ) {
if ( n <= 1 ) {
return 1;
} else {
return n * factorial( n – 1 );
}
}

int factorial( int n ) {


return (n <= 1) ? 1 : n * factorial( n – 1 );
}
Analyze the algorithm
Thus, we may analyze the run time of this function as follows:

Θ(1) n 1
T! ( n )  
T! ( n  1)  Θ(1) n  1

The analysis of the run time of this function yields a recurrence relation:
T!(n) = T!(n – 1) + Q(1) T!(1) = Q(1)

Replace each Landau symbol with a representative function:

T!(n) = T!(n – 1) + 1 T!(1) = 1


Analyze an algorithm

we can examine the first few steps:


T!(n) = T!(n – 1) + 1
= T!(n – 2) + 1 + 1 = T!(n – 2) + 2
= T!(n – 3) + 3

From this, we see a pattern:


T!(n) = T!(n – k) + k
Analyze the algorithm

If k = n – 1 then
T!(n) = T!(n – (n – 1)) + n – 1
= T!(1) + n – 1
=1+n–1=n

Thus, T!(n) = Q(n)


Merge-Sort
 Merge-sort on an input Algorithm mergeSort(S, C)
sequence S with n elements Input sequence S with n
consists of three steps: elements, comparator C
Output sequence S sorted
 Divide: partition S into two
according to C
sequences S1 and S2 of about
n/2 elements each if S.size() > 1
(S1, S2)  partition(S, n/2)
 Recur: recursively sort S1 and S2
mergeSort(S1, C)
 Conquer: merge S1 and S2 into a mergeSort(S2, C)
unique sorted sequence
S  merge(S1, S2)
Merging Two Sorted Sequences

 The conquer step of Algorithm merge(A, B)


merge-sort consists of Input sequences A and B with
merging two sorted n/2 elements each
sequences A and B into a Output sorted sequence of A  B
sorted sequence S
containing the union of the S  empty sequence
elements of A and B while A.isEmpty()  B.isEmpty()
 Merging two sorted if A.first().element() < B.first().element()
sequences, each with n/2 S.insertLast(A.remove(A.first()))
elements and implemented else
by means of a doubly S.insertLast(B.remove(B.first()))
linked list, takes O(n) time while A.isEmpty()
S.insertLast(A.remove(A.first()))
while B.isEmpty()
S.insertLast(B.remove(B.first()))
return S
Merge-Sort Tree
 An execution of merge-sort is depicted by a binary tree
 each node represents a recursive call of merge-sort and stores
 unsorted sequence before the execution and its partition
 sorted sequence at the end of the execution
 the root is the initial call
 the leaves are calls on subsequences of size 0 or 1

7 2  9 4  2 4 7 9

7  2  2 7 9  4  4 9

77 22 99 44


Execution Example
 Partition

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 2 9 4  2 4 7 9 3 8 6 1  1 3 8 6

7 2  2 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Recursive call, partition

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

7 2  2 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Recursive call, partition

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Recursive call, base case

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)

 Recursive call, base case

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Merge

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Merge Sort 39
Execution Example (cont.)
 Recursive call, …, base case, merge

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Merge

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 8 6

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)

 Recursive call, …, merge, merge

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 6 8

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Execution Example (cont.)
 Merge

7 2 9 43 8 6 1  1 2 3 4 6 7 8 9

7 29 4 2 4 7 9 3 8 6 1  1 3 6 8

722 7 9 4  4 9 3 8  3 8 6 1  1 6

77 22 99 44 33 88 66 11


Analysis of Merge-Sort
 The height h of the merge-sort tree is O(log n)
 at each recursive call we divide in half the sequence,
 The overall amount or work done at the nodes of depth i is O(n)
 we partition and merge 2i sequences of size n/2i
 we make 2i1 recursive calls
 Thus, the total running time of merge-sort is O(n log n)
depth #seqs size
0 1 n

1 2 n/2

i 2i n/2i

… … …
Compute Sum of 1…n
n
 Problem: Running sum (  i)
1
Recursive solution:
RunningSum(1) = 1
RunningSum(n) = n + RunningSum(n-1)

Recursive algorithm:
int RunningSum(int n) {
declare sum
if (n equal to 1)
return 1;
else
sum = n + RunningSum(n-1)
return sum
}
Executing RunningSum
res = RunningSum(4);

return value = 10 RunningSum(4)

return 4 + RunningSum(3);

return value = 6 RunningSum(3)

return 3 + RunningSum(2);

return value = 3 RunningSum(2)

return 2 + RunningSum(1);

return value = 1 RunningSum(1)

return 1;
Now you analyze the algorithm
Compute power
 Recursive definition of bn :
bn = 1 if n = 0
bn = b  bn–1 if n > 0
 Simple recursive power algorithm:
Easy case: solved directly.
To compute bn:
1. If n = 0:
1.1. Terminate with answer 1.
2. If n > 0:
2.1. Terminate with answer b  bn–1.

Hard case: solved by computing bn–


1, which is easier since n–1 is closer

than n to 0.
Design the algoritm

int power (int b, int n) {


if n equal to 0
return 1;
else
return b * power(b, n-1);
}
Now analyze the algorithm
A smart solution

 Idea: b1000 = b500  b500, and b1001 = b  b500  b500.


 Alternative recursive definition of bn:
bn = 1 if n = 0
bn = bn/2  bn/2 if n > 0 and n is even
bn = b  bn/2  bn/2 if n > 0 and n is odd
(Recall: n/2 discards the remainder if n is odd.)
Recursive solution

 Smart recursive power algorithm:


To compute bn:
Easy case: solved directly.
1. If n = 0:
1.1. Terminate with answer 1.
Hard case: solved by comput-
2. If n > 0:
ing bn/2, which is easier since
2.1. Let p be bn/2.
n/2 is closer than n to 0.
2.2. If n is even:
2.2.1. Terminate with answer p  p.
2.3. If n is odd:
2.3.1. Terminate with answer b  p  p.
Design an algorithm

int power (int b, int n) {


if (n equal to 0)
return 1;
else {
Set p to power(b, n/2);
if (n mod 2 equal to 0)
return p * p;
else
return b * p * p;
}
}
Now analyze the algorithm
Analysis

 Analysis (counting multiplications):


Each recursive power algorithm performs the same number of multiplications
as the corresponding non-recursive algorithm. So their time complexities are
the same:

non-recursive recursive
Simple power algorithm O(n) O(n)
Smart power algorithm O(log n) O(log n)
Recursive Squaring
 We can derive a more efficient linearly
recursive algorithm by using repeated
squaring:
 1 if x  0

p ( x, n)   x  p ( x, ( n  1) / 2) 2 if x  0 is odd
 p ( x, n / 2) 2 if x  0 is even

 For example,
24 = 2(4/2)2 = (24/2)2 = (22)2 = 42 = 16
25 = 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 32
26 = 2(6/ 2)2 = (26/2)2 = (23)2 = 82 = 64
27 = 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128.

56
A Recursive Squaring Method
Algorithm Power(x, n):
Input: A number x and integer n = 0
Output: The value xn
if n = 0 then
return 1
if n is odd then
y = Power(x, (n - 1)/ 2)
return x · y ·y
else
y = Power(x, n/ 2)
return y · y
Analyzing the algorithm
Algorithm Power(x, n):
Input: A number x and integer n
=0
Output: The value xn
if n = 0 then Each time we make a
recursive call we halve the
return 1 value of n; hence, we make
if n is odd then log n recursive calls. That
y = Power(x, (n - 1)/ 2) is, this method runs in
O(log n) time.
return x · y · y
else
It is important that we
y = Power(x, n/ 2) used a variable twice here
return y · y rather than calling the
method twice.
Exercises
Fibonacci sequence problem

The Fibonacci sequence:


{fn } = 0,1,1,2,3,5,8,13,21,34,55
 Mathematical Definition:

f ( n )  f ( n  1)  f ( n  2)
f (1)  1
f (0 )  1

 In other words, the n-th Fibonacci number is the sum of the previous two
Fibonacci numbers.
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
Linear search problem
PROBLEM: Start with a collection of names N1, N2, ..., N10000,
and corresponding telephone numbers T1, T2, ..., T10000.
Given a name, Name, find a telephone number for that
name if a match on an Ni occurs; otherwise, print "Not
Found".
Note: In the book, subscripts are used for N1, N2, etc.
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
FIND LARGEST Problem

PROBLEM: Given n, the size of a list, and a list of n numbers, find


the largest number in the list.
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
Binary Search problem

 Searching a sorted list


 How can we exploit the structure that a sorted list
provides?
 Start in the middle and determine in which half of the list
our target lives
 Repeatthis procedure eliminating half of the remaining list
elements on each iteration
 What is the maximum number of comparisons required here?
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
Computing Prefix Averages Problem
 We further illustrate asymptotic analysis with two
algorithms for prefix averages
 The i-th prefix average of an array X is average of
the first (i  1) elements of X:
A[i]  (X[0]  X[1]  …  X[i])/(i+1)
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
Examples of Algorithms – Computing the
Greatest Common Divisor of Two Integers
The greatest common divisor of two non-negative, not-both-zero integers
m and n, denoted gcd(m, n), is defined as the largest integer that divides
both m and n evenly, until the remainder is zero
 Euclid’s algorithm is based on repeated application of equality until the
second number becomes 0
gcd(m, n) = gcd(n, m mod n)
 For example gcd(60, 24) can be computed as follows:
gcd(60, 24) = gcd(24, 12) = gcd(12, 0) = 12

 x, if y  0
gcd( x, y )  
gcd( y, x mod y ), otherwise
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm
Selection Sort
n is the size of unsorted list.
if n is 1,
- array is sorted
else
- (1) find the smallest element in the
unsorted array list
- (2) swap the 1st element in the
unsorted array with the smallest
element
- (3) sort the remaining unsorted array
Design a recursive algorithm

 Write recursive algorithm, and


 Analyze the algorithm

You might also like