Reading: Chapter 10
Fabulously complex structure, simple procedures
Recursion?? What's that?
Recursion is the concept of well-defined self-reference.
A Sierpinski gasket is three half-sized Sierpinski gaskets arranged in a triangle.

Recursion turns up in mathematics all the time!
Recurrences are recursive mathematical formulas.
Example:
{ 1 if n = 1 or n = 2
F(n) = {
{ F(n - 2) + F(n - 1) otherwise
This is the definition of the famed Fibonacci sequence
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ... |
|---|---|---|---|---|---|---|---|---|
| F(n) | 1 | 1 | 2 | 3 | 5 | 8 | 13 | ... |
But recursion is just as much a computer science concept!
Problem EXPONENTIATION:
Input: a number x and a positive integer n.
Output: the value xn.
We can first write a recurrence.
{ 1 if n = 0
E(x,n) = {
{ x E(x, n - 1) if n > 0
Now we write a program.
double exponentiate(double x, int n) {
if(n == 0) {
return 1.0;
} else {
return x * exponentiate(x, n - 1);
}
}
int main() {
double x;
int n;
cout << "Take what to the what? ";
cin >> x >> n;
cout << exponentation(x, n) << endl;
return 0;
}
To trace how the program works, we use a call stack.
exponentation(2, 5) returns 32 exponentation(2, 4) returns 16 exponentation(2, 3) returns 8 exponentation(2, 2) returns 4 exponentation(2, 1) returns 2 exponentation(2, 0) returns 1
Couldn't a recursive
algorithm go on forever?
Every recursive algorithm must have a case in which it does not recurse - called the base case. (Just like induction!)
But what about this instead?
If n is even, xn = (x2)n/2.
If n is odd, xn = x * (x2)(n-1)/2.
This can be a lot faster.
double exponentatiate(double x, int n) {
if(n == 0) {
return 1.0;
} else if(n % 2 == 0) {
return fastExp(x * x, n / 2);
} else {
return x * fastExp(x * x, (n - 1) / 2);
}
}
The call stack for (x=2,n=5).
exponentation( 2, 5) returns 32 exponentation( 4, 2) returns 16 exponentation( 16, 1) returns 16 exponentation(256, 0) returns 1
| | | $$$ | | @@@@@ | | ####### | | ---+-------+-------+--- a b c
Goal: move towers from a to b.
Rules:
Pseudocode:
Algorithm Hanoi(disk, src, dst, space) if disk = 0 then Move disk from src to dst. else Hanoi(disk - 1, src, spare, dst) Move disk from src to dst. Hanoi(disk - 1, spare, dst, src) end of ifTo start, we call Hanoi(2, a, b, c).
We can use a call stack to trace this, or we can use a call tree:
2,a,b,c
1,a,c,b 1,c,b,a
0,a,b,c 1,b,c,a 1,c,a,b 1,a,b,c
How much longer 'til the world
ends?
Define a recurrence:
{ 1 if n = 1
H(n) = {
{ H(n-1) + 1 + H(n-1) if n > 1
Solve:
Prove:
n H(n) 1 1 2 3 3 7 4 15 5 31 : :
A REAL puzzle:
What's the best algorithm
for moving n disks using 4 pegs?