Comp171 Recursion 1

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

COMP171

Spring 2009

Recursion
Recursion / Slide 2

Recursion
In some problems, it may be natural to define
the problem in terms of the problem itself.
Recursion is useful for problems that can be
represented by a simpler version of the same
problem.
Example: the factorial function
6! = 6 * 5 * 4 * 3 * 2 * 1
We could write:
6! = 6 * 5!
Recursion / Slide 3

Example 1: factorial function


In general, we can express the factorial
function as follows:
n! = n * (n-1)!
Is this correct? Well… almost.
The factorial function is only defined for
positive integers. So we should be a bit more
precise:
n! = 1 (if n is equal to 1)
n! = n * (n-1)! (if n is larger than 1)
Recursion / Slide 4

factorial function
The C++ equivalent of this definition:
int fac(int numb){
if(numb<=1)
return 1;
else
return numb * fac(numb-1);
}

recursion means that a function calls itself


Recursion / Slide 5

factorial function
Assume the number typed is 3, that is, numb=3.
fac(3) :
3 <= 1 ? No.
fac(3) = 3 * fac(2)
fac(2) :
2 <= 1 ? No.
fac(2) = 2 * fac(1)
fac(1) :
1 <= 1 ? Yes.
return 1 int fac(int numb){
fac(2) = 2 * 1 = 2 if(numb<=1)
return fac(2) return 1;
fac(3) = 3 * 2 = 6 else
return fac(3) return numb * fac(numb-1);
}
fac(3) has the value 6
Recursion / Slide 6

factorial function
For certain problems (such as the factorial function), a
recursive solution often leads to short and elegant code.
Compare the recursive solution with the iterative solution:

Recursive solution Iterative solution

int fac(int numb){ int fac(int numb){


if(numb<=1) int product=1;
return 1; while(numb>1){
else product *= numb;
return numb*fac(numb-1); numb--;
} }
return product;
}
Recursion / Slide 7

Recursion
To trace recursion, recall that function calls operate as
a stack – the new function is put on top of the caller

We have to pay a price for recursion:


„ calling a function consumes more time and memory than
adjusting a loop counter.
„ high performance applications (graphic action games,
simulations of nuclear explosions) hardly ever use recursion.

In less demanding applications recursion is an


attractive alternative for iteration (for the right
problems!)
Recursion / Slide 8

Iteration
If we use iteration, we must be careful not to
create an infinite loop by accident:

for(int incr=1; incr!=10;incr+=2)


...

Oops!
int result = 1;
while(result >0){
...
result++;
} Oops!
Recursion / Slide 9

Recursion
Similarly, if we use recursion we must be
careful not to create an infinite chain of
function calls:
int fac(int numb){ Oops!
return numb * fac(numb-1); No termination
}
condition
Or:
int fac(int numb){
if (numb<=1)
return 1;
else
return numb * fac(numb+1);
}
Oops!
Recursion / Slide 10

Recursion

We must always make sure that the recursion


bottoms out:

A recursive function must contain at least one


non-recursive branch.
The recursive calls must eventually lead to a
non-recursive branch.
Recursion / Slide 11

Recursion

Recursion is one way to decompose a task into


smaller subtasks. At least one of the subtasks is
a smaller example of the same task.
The smallest example of the same task has a
non-recursive solution.

Example: The factorial function


n! = n * (n-1)! and 1! = 1
Recursion / Slide 12

Example 2: Fibonacci numbers


Fibonacci numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
where each number is the sum of the preceding
two.

Recursive definition:
„ F(0) = 0;
„ F(1) = 1;
„ F(number) = F(number-1)+ F(number-2);
Recursion / Slide 13

Example 3: Fibonacci numbers


//Calculate Fibonacci numbers using recursive function.
//A very inefficient way, but illustrates recursion well
int fib(int number)
{
if (number == 0) return 0;
if (number == 1) return 1;
return (fib(number-1) + fib(number-2));
}
int main(){ // driver function
int inp_number;
cout << "Please enter an integer: ";
cin >> inp_number;
cout << "The Fibonacci number for "<< inp_number
<< " is "<< fib(inp_number)<<endl;
return 0;
}
Recursion / Slide 14

Copyright © 2000 by Brooks/Cole Publishing Company


A division of International Thomson Publishing Inc.
Recursion / Slide 15

Trace a Fibonacci Number


int fib(int num)
{
Assume the input number is 4, that is, num=4: if (num == 0) return 0;
if (num == 1) return 1;
fib(4): return
4 == 0 ? No; 4 == 1? No. (fib(num-1)+fib(num-2));
}
fib(4) = fib(3) + fib(2)
fib(3):
3 == 0 ? No; 3 == 1? No.
fib(3) = fib(2) + fib(1)
fib(2):
2 == 0? No; 2==1? No.
fib(2) = fib(1)+fib(0)
fib(1):
1== 0 ? No; 1 == 1? Yes.
fib(1) = 1;
return fib(1);
Recursion / Slide 16

Trace a Fibonacci Number


fib(0):
0 == 0 ? Yes.
fib(0) = 0;
return fib(0);
fib(2) = 1 + 0 = 1;
return fib(2);
fib(3) = 1 + fib(1)
fib(1):
1 == 0 ? No; 1 == 1? Yes
fib(1) = 1;
return fib(1);
fib(3) = 1 + 1 = 2;
return fib(3)
Recursion / Slide 17

Trace a Fibonacci Number


fib(2):
2 == 0 ? No; 2 == 1? No.
fib(2) = fib(1) + fib(0)
fib(1):
1== 0 ? No; 1 == 1? Yes.
fib(1) = 1;
return fib(1);
fib(0):
0 == 0 ? Yes.
fib(0) = 0;
return fib(0);
fib(2) = 1 + 0 = 1;
return fib(2);
fib(4) = fib(3) + fib(2)
= 2 + 1 = 3;
return fib(4);
Recursion / Slide 18

Fibonacci number w/o recursion


//Calculate Fibonacci numbers iteratively
//much more efficient than recursive solution

int fib(int n)
{
int f[n+1];
f[0] = 0; f[1] = 1;
for (int i=2; i<= n; i++)
f[i] = f[i-1] + f[i-2];
return f[n];
}
Recursion / Slide 19

Example 3: Binary Search


„ Search for an element in an array
Sequential search
Binary search

„ Binary search
Compare the search element with the
middle element of the array
If not equal, then apply binary search to
half of the array (if not empty) where the
search element would be.
Recursion / Slide 20

Binary Search with Recursion


// Searches an ordered array of integers using recursion
int bsearchr(const int data[], // input: array
int first, // input: lower bound
int last, // input: upper bound
int value // input: value to find
)// output: index if found, otherwise return –1

{ int middle = (first + last) / 2;


if (data[middle] == value)
return middle;
else if (first >= last)
return -1;
else if (value < data[middle])
return bsearchr(data, first, middle-1, value);
else
return bsearchr(data, middle+1, last, value);
}
Recursion / Slide 21

Binary Search
int main() {
const int array_size = 8;
int list[array_size]={1, 2, 3, 5, 7, 10, 14, 17};
int search_value;

cout << "Enter search value: ";


cin >> search_value;
cout << bsearchr(list,0,array_size-1,search_value)
<< endl;

return 0;
}
Recursion / Slide 22

Binary Search w/o recursion


// Searches an ordered array of integers
int bsearch(const int data[], // input: array
int size, // input: array size
int value // input: value to find
){ // output: if found,return
// index; otherwise, return -1

int first, last, upper;


first = 0;
last = size - 1;
while (true) {
middle = (first + last) / 2;
if (data[middle] == value)
return middle;
else if (first >= last)
return -1;
else if (value < data[middle])
last = middle - 1;
else
first = middle + 1;
}
}
Recursion / Slide 23

Recursion General Form


How to write recursively?

int recur_fn(parameters){
if(stopping condition)
return stopping value;
// other stopping conditions if needed
return function of recur_fn(revised parameters)

}
Recursion / Slide 24

Example 4: exponential function


How to write exp(int numb, int power)
recursively?

int exp(int numb, int power){


if(power ==0)
return 1;
return numb * exp(numb, power -1);
}
Recursion / Slide 25

Example 5: number of zero


Write a recursive function that counts the number of zero
digits in an integer
zeros(10200) returns 3.
int zeros(int numb){
if(numb==0) // 1 digit (zero/non-zero):
return 1; // bottom out.
else if(numb < 10 && numb > -10)
return 0;
else // > 1 digits: recursion
return zeros(numb/10) + zeros(numb%10);
}
zeros(10200)
zeros(1020) + zeros(0)
zeros(102) + zeros(0) + zeros(0)
zeros(10) + zeros(2) + zeros(0) + zeros(0)
zeros(1) + zeros(0) + zeros(2) + zeros(0) + zeros(0)
Recursion / Slide 26

Example 6: Towers of Hanoi

„ Only one disc could be moved at a time


„ A larger disc must never be stacked above
a smaller one
„ One and only one extra needle could be
used for intermediate storage of discs
Recursion / Slide 27

Towers of Hanoi
void hanoi(int from, int to, int num)
{
int temp = 6 - from - to; //find the temporary
//storage column
if (num == 1){
cout << "move 1 disc from " << from
<< " to " << to << endl;
}
else {
hanoi(from, temp, num - 1);
cout << "move disc " << num << " from " << from
<< " to " << to << endl;
hanoi(temp, to, num - 1);
}
}
Recursion / Slide 28

Towers of Hanoi
int main() {
int num_disc; //number of discs

cout << "Please enter a positive number (0 to quit)";


cin >> num_disc;

while (num_disc > 0){


hanoi(1, 3, num_disc);
cout << "Please enter a positive number ";
cin >> num_disc;
}
return 0;
}
Recursion / Slide 29

Example of Towers of Hanoi (4 discs)


hanoi(1,3,4)

hanoi(1,2,3) Move disc 4 hanoi(2,3,3)


from 1 to 3

hanoi(1,3,2) hanoi(2,1,2)

hanoi(1,2,1) hanoi(2,3,1)

Move disc 2 Move disc 3 Move disc 2 Move disc 3


from 1 to 3 from 1 to 2 from 2 to 1 from 2 to 3

hanoi(2,3,1) hanoi(3,1,1)

hanoi(3,2,2) hanoi(1,3,2)

hanoi(3,1,1) hanoi(1,2,1)

Move disc 2 Move disc 2


from 3 to 2 from 1 to 3

hanoi(1,2,1) hanoi(2,3,1)
Recursion / Slide 30

Example of Towers of Hanoi (cont’d)


Move disc 4
num_disc=4 from 1 to 3

hanoi(1,2,1) hanoi(2,3,1)
Move disc 2 Move disc 2
from 1 to 3 from 2 to 1

hanoi(2,3,1) hanoi(3,1,1)
Move disc 3 Move disc 3
from 1 to 2 from 2 to 3

hanoi(3,1,1) hanoi(1,2,1)
Move disc 2 Move disc 2
from 3 to 2 from 1 to 3

hanoi(1,2,1) hanoi(2,3,1)
Basic Mathematics
Chapter 1 (1.2 and 1.3) Weiss
Recursion / Slide 32

Logarithms

Definition: X A = B if and only if log x B = A


Theorem 1.1: log c B
log A B =
„ Proof: apply the definition log c A
Theorem 1.2: log AB = log A + log B
„ Proof: again apply the definition
log A : default is base 2
„ log 2 = 1, log 1 = 0, …
amn = (am )n = (an)m
am+n = am an
• alog n = nlog a
• log (a/b ) = log a - log b
Recursion / Slide 33

Mathematical Foundation

•Series and summation:


1 + 2 + 3 + ……. N = N(N+1)/2 (arithmetic series)

1 + r+ r2 + r3 +………rN-1 = (1- rN)/(1-r), (geometric series)


≤ 1/(1-r) , r < 1, large N

•Sum of squares:
1 + 22 + 32 +………N2 = N(N + 1)(2N + 1)/6
(proof by induction)
Recursion / Slide 34

Proof By Induction

• (2πn)0.5 (n/e)n ≤ n! ≤ (2πn)0.5 (n/e)n + (1/12n) ?


• Prove that a property holds for input n= 1 (base case)

• Assume that the property holds for input size 1,…n. Show
that the property holds for input size n+1.

• Then, the property holds for all input sizes, n.


Recursion / Slide 35

Try this: Prove that the sum of 1+2+…..+n = n(n+1)/2

Proof: 1(1+1)/2 = 1
Thus the property holds for n = 1 (base case)

Assume that the property holds for n=1,…,m,


Thus 1 + 2 +…..+m = m(m+1)/2

We will show that the property holds for n = m + 1, that


is 1 + 2 + ….. + m + m + 1 = (m+1)(m+2)/2

This means that the property holds for n=2 since we


have shown it for n=1
Again this means that the property holds for n=3 and
then for n=4 and so on.
Recursion / Slide 36

Now we show that the property holds for n = m + 1, that is 1 +


2 + ….. + m + m + 1 = (m+1)(m+2)/2
assuming that 1 + 2 +…..+m = m(m+1)/2

1 + 2 +…..+m + (m+1) = m(m+1)/2 + (m+1)


= (m+1)(m/2 + 1)
= (m+1)(m+2)/2
Recursion / Slide 37

Sum of Squares

Now we show that


1 + 22 + 32 +………n2 = n(n + 1)(2n + 1)/6

1(1+1)(2+1)/6 = 1
Thus the property holds for n = 1 (base case)

Assume that the property holds for n=1,..m,


Thus 1 + 22 + 32 +………m2 = m(m + 1)(2m + 1)/6
and show the property for m + 1, that is show that
1 + 22 + 32 +………m2 +(m+1)2 = (m+1)(m + 2)(2m + 3)/6
Recursion / Slide 38

1 + 22 + 32 +………m2 + (m+1)2 = m(m + 1)(2m + 1)/6 +


(m+1)2

=(m+1)[m(2m+1)/6 +m+1]

= (m+1)[2m2 + m + 6m +6]/6

= (m+1)(m + 2)(2m + 3)/6


Recursion / Slide 39

Fibonacci Numbers

Sequence of numbers, F0 F1 , F2 , F3 ,…….

F0 = 1, F1 = 1,

Fi = Fi-1 + Fi-2 ,

F2 = 2, F3 = 3, F4 = 5, F5 = 8
Recursion / Slide 40

Prove that Fn+1 < (5/3)n+1 ,

F2 < (5/3 )2

Assume that the property holds for 1,…k


Thus Fk+1 < (5/3)k+1, Fk < (5/3)k

Fk+2 = Fk + Fk+1 ,

< (5/3)k + (5/3)k+1

= (5/3)k (5/3 + 1)

< (5/3)k (5/3)2

You might also like