Recursion Note
Recursion Note
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.
• 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.
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
4: else
5: return Recursion(subcase(s))
6: end if
7: end procedure
2 Examples
2.1 Peasant multiplication
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
int main () {
printf ("%d \n" , multiply (6 , 5) );
}
print ( multiply (6 , 5) )
When we replace the addition with the multiplication and the multiplication with the power in the multiply
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.
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.
int main () {
printf ("% lld \n " , power (6 , 5) ) ;
}
print ( pow (6 , 5) )
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.
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.
int main () {
printf ("% lld \n " , fact (15) );
}
3
2.4 Calculate Fibonacci numbers
(
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.
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
int main () {
printf ("% lld \n " , fibo (5) ) ;
}
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
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
int main () {
printf ("% lld \n " , binom (5 , 3) ) ;
}
print ( binom (5 , 3) )
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
odd, we have c(n) = c((3n + 1)/2) + 2. This gives us the following algorithm:
1: procedure Collatz n ( )
2: if n=1 then
3: return 0
4: else if n is even then
6: else
7: return Collatz ((3n + 1)/2) + 2 . Recurse
8: end if
9: end procedure
5
else if ( n & 1) return collatz ((3 * n + 1) / 2) + 2;
return collatz (n / 2) + 1;
}
int main () {
printf ("% lld \n " , collatz (13) ) ;
}
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 objective of the puzzle is to move the entire stack to another rod, obeying the following simple
rules:
2. Each move consists of taking the upper disk from one of the stacks and placing it on top of another
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.
2: if n>0 then
3: Hanoi(n − 1, src, tmp, dst) . Recurse
6: end if
7: end procedure
6
An implementation by Python can be found below.
A = [3 , 2 , 1]
B = []
C = []
hanoi (3 , A , B , C)