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

Recursion Note

Uploaded by

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

Recursion Note

Uploaded by

Minh Ngô
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Recursion

Minh Ngo

1 Definitions
Definition 1. Reduction is a technique to reduce a problem X to a problem Y that we already have an algorithm

to solve.

Definition 2. Recursion is a kind of reduction, which can be described as:

• If the given instance of the problem can be solved directly, solve it directly.

• Otherwise, reduce it to one or more simpler instance(s) of the same problem. This is analogous to induction
hypothesis in mathematics.

Definition 3. A function which calls itself directly or indirectly is a recursive function .

In a recursive program, the solution to the base case is provided and the solution of the bigger problem is

expressed in terms of smaller problems. A typical recursive algorithm can be expressed in pseudocode as following:

Algorithm 1 Recursion

1: procedure Recursion (case)

2: if Base case then


3: return solution of base case

4: else
5: return Recursion(subcase(s))

6: end if
7: end procedure

2 Examples
2.1 Peasant multiplication

Peasant multiplication algorithm is based on the following simple identity:


0
 if x=0
x · y = 2 · bx/2c · y if x is even

2 · bx/2c · y + y x is odd

if

So we can multiply x and y by multiplying x0 and y 0 , then may be add y to the result (if x is odd). This
multiplication is simpler since x0 < x, and if we keep decreasing x, we will eventually get to 0. We can express the
process algorithmically as follow.

1
Algorithm 2 Peasant multiplication

1: procedure Multiply x, y ( )

2: if x=0 then
3: return 0
4: else
5: prod ← 2 · Multiply(bx/2c, y) . Recurse

6: if x is odd then
7: prod ← prod + y
8: end if
9: return prod
10: end if
11: end procedure

An implementation of the above algorithm in C.

# include < stdio .h >

int multiply ( int x , int y) {


if (x == 0) return 0;
int prod = 2 * multiply (x / 2, y) ;
if (x & 1) return prod + y ;
return prod ;
}

int main () {
printf ("%d \n" , multiply (6 , 5) );
}

An implementation of the above algorithm in Python.

def multiply (x , y):


if x == 0: return 0
prod = 2 * multiply ( x // 2, y)
if x & 1: return prod + y
return prod

print ( multiply (6 , 5) )

2.2 Calculate power

When we replace the addition with the multiplication and the multiplication with the power in the multiply

algorithm above, we will receive a recursive algorithm to calculate power.

The identity for power is similar:


1

2
if y=0
y
x = xby/2c if y>0 and y even
 by/2c 2

x ·x if y>0 and y odd

y
So we can calculate x by taking the power y/2 of x, then take it square and may be multiply y. This problem

is simpler, and if we keep decreasing y, we will get to base case y = 0. Algorithmically, the identity looks like this.

Algorithm 3 Binary power

1: procedure Power x, y( )

2: if y=0 then
3: return 1
4: else
5: pow ← Power(x, by/2c) . Recurse

6: if y is odd then
7: pow ← pow · x
8: end if
9: return pow
10: end if
11: end procedure

2
An implementation of the above algorithm in C.

# include < stdio .h >

long long power ( int x , int y ) {


if (y == 0) return 1;
long long pow = power (x , y / 2) ;
if (y & 1) return pow * pow * 1 ll * x;
else return pow * pow ;
}

int main () {
printf ("% lld \n " , power (6 , 5) ) ;
}

An implementation of the above algorithm in Python.

def power (x , y):


if y == 0: return 1
pwr = power (x , y // 2)
if y & 1: return pow ** 2 * x
return pow ** 2

print ( pow (6 , 5) )

2.3 Calculate factorial

The algorithm for factorial makes use of this simple identity

n! = (n − 1)! · n

So to calculate n!, we just need to calculate (n−1)! and the multiply the result with n. And when we keep decreasing
n, we will eventually reach base case 0! = 1.

Algorithm 4 Calculate factorial

1: procedure Fact x ( )

2: if x=0 then
3: return 1
4: else
5: return x· Fact (x − 1) . Recurse

6: end if
7: end procedure

An implementation of the above algorithm in C. Note that in C, we can only calculate small factorial using

built-in data type. If we want to calculate large factorial, we have to use Python or write an ad hoc multiplication

of a large number and a small number, which we will discuss in a different note.

# include < stdio .h >

long long fact ( int x) {


if (x == 0) return 1;
else return 1 ll * x * fact ( x - 1) ;
}

int main () {
printf ("% lld \n " , fact (15) );
}

An implementation of the above algorithm in Python.

def fact (x):


if x == 0: return 1
return x * fact (x - 1)

print ( fact (6) )

3
2.4 Calculate Fibonacci numbers

The Fibonacci sequence (fn ) is defined as following:

(
1 if n = 0, 1
fn =
fn−1 + fn−2 if n ≥ 2.

Important note: Every sequenced that is defined by recursive identity like this is susceptible to recursion.

The pseudocode for Fibonacci algorithm:

Algorithm 5 Calculate Fibonacci numbers

1: procedure Fibo x
( )

2: if x≤1 then
3: return 1
4: else
5: return Fibo (x − 1) + Fibo (x − 2) . Recurse

6: end if
7: end procedure

An implementation of the above algorithm in C.

# include < stdio .h >

int fibo ( int n) {


if (n <= 1) return 1;
return fibo (n - 1) + fibo (n - 2) ;
}

int main () {
printf ("% lld \n " , fibo (5) ) ;
}

An implementation of the above algorithm in Python.

def fibo (x):


if x <= 1: return 1
return fibo (x - 1) + fibo (x - 2)

print ( fibo (6) )

2.5 Calculate binomial coefficients


n

Binomial coefficients
k are the number of ways to select a set of k elements from n different elements without

taking into account the order of arrangement of these elements (i.e., the number of unordered sets).

To calculate binomial coefficient, the first method is to use the analytic formula

 
n n!
=
k k!(n − k)!

This formula can be easily deduced from the problem of ordered arrangement (number of ways to select k different

elements from n different elements). The second way is to use the recurrence formula, discovered by Pascal:

     
n n−1 n−1
= +
k k−1 k

It is easy to deduce this using the analytic formula.


n

Note that for n < k, the value of
k is assumed to be 0.

Using the recurrence formula, we have the following algorithm:

4
Algorithm 6 Calculate binomial coefficients

1: procedure Binom n, k ( )

2: if n<k then
3: return0
4: else if k=0 or k=n then
5: return 1

6: else
7: return Binom (n − 1, k − 1) + Binom (n − 1, k) . Recurse

8: end if
9: end procedure

An implementation of the above algorithm in C.

# include < stdio .h >

int binom ( int n , int k) {


if (n < k) return 0;
if (k == 0 || k == n) return 1;
return binom (n - 1, k - 1) + binom ( n - 1, k);
}

int main () {
printf ("% lld \n " , binom (5 , 3) ) ;
}

An implementation of the above algorithm in Python.

def binom (n , k):


if n < k : return 0
if k == 0 or k == n: return 1
return binom (n - 1, k - 1) + binom ( n - 1, k)

print ( binom (5 , 3) )

2.6 Length of Collatz sequences

The infamous Collatz's conjecture stated as following: Given a positive integer x, we keep do the following operation
(
x
2 if x is even
x=
3x + 1 if x is odd

then after a finite number of operations, we will arrive at 1. Now, if we assume that the conjecture is actually

correct, we want to compute the number of operations that will reduce x to 1.


Now, letc(n) denote the number of such operations. Then if n is even, we have c(n) = c(n/2) + 1 and if n is

odd, we have c(n) = c((3n + 1)/2) + 2. This gives us the following algorithm:

Algorithm 7 Length of Collatz sequence

1: procedure Collatz n ( )

2: if n=1 then
3: return 0
4: else if n is even then

5: return Collatz (n/2) + 1 . Recurse

6: else
7: return Collatz ((3n + 1)/2) + 2 . Recurse

8: end if
9: end procedure

An implementation of the above algorithm in C.

# include < stdio .h >

int collatz ( int n) {


if (n == 1) return 0;

5
else if ( n & 1) return collatz ((3 * n + 1) / 2) + 2;
return collatz (n / 2) + 1;
}

int main () {
printf ("% lld \n " , collatz (13) ) ;
}

An implementation of the above algorithm in Python.

def collatz ( n):


if n == 1: return 0
elif n & 1: return collatz ((3 * n + 1) // 2) + 2
return collatz (n // 2) + 1

print ( collatz (13) )

2.7 Tower of Hanoi

This infamous problem was first published by Eduouard Lucas is 1883. The puzzle can be described as following:

The puzzle consists of three rods and a number of disks of different sizes, which can slide onto any rod.

The puzzle starts with the disks in a neat stack in ascending order of size on one rod, the smallest at

the top, thus making a conical shape.

The objective of the puzzle is to move the entire stack to another rod, obeying the following simple

rules:

1. Only one disk can be moved at a time.

2. Each move consists of taking the upper disk from one of the stacks and placing it on top of another

stack or on an empty rod.

3. No larger disk may be placed on top of a smaller disk

H¼nh 1: The Tower of Hanoi puzzle

The crux to solving this puzzle is to solve it recursively. So instead of trying to solve the entire puzzle at once,

we will solve it recursively. First, we try to moving just the largest disk. We can't move it at the beginning, because

all the other disks are in the way. So first we have to move those n − 1 disks to a spare peg. And then after we move
the largest disk, we have to move those n − 1 disks back on top of it. So now, the problem reduces to solving two
instances of the same problem with n − 1. The base case is when n = 0, we have to do nothing at all.
Using this recursive scheme, we have the following recurrence relation for the number of steps we need to solve

this puzzle. Let cn be the number of steps we need to solve this puzzle for n disks, then cn = 2cn−1 + 1. It's easy

to see from this recurrence relation that the general formula is 2n − 1, and we can prove this easily with induction.

Pseudocode for algorithm to solve the puzzle

Algorithm 8 Tower of Hanoi

1: procedure Hanoi n, src, dst, tmp


( )

2: if n>0 then
3: Hanoi(n − 1, src, tmp, dst) . Recurse

4: move diskn from src to dst


5: Hanoi(n − 1, tmp, dst, src) . Recurse

6: end if
7: end procedure

6
An implementation by Python can be found below.

A = [3 , 2 , 1]
B = []
C = []

def hanoi (n , src , dst , tmp ) :


if n > 0:
hanoi (n - 1 , src , tmp , dst )
dst . append ( src . pop () )
print (A , B , C , ' ######### ', sep = '\ n ')
hanoi (n - 1 , tmp , dst , src )

hanoi (3 , A , B , C)

You might also like