PCS4
Week 3:
recursion (book: section 7.15)
Recursion
2
Remember from Math-lessons:
mathematical induction?
We have a functional proposition,
say P(n), where n ϵ {7, 8, 9, 10, 11, 12, 13, . . .}.
Suppose we can prove that: "starting point"
• P(7) is true, and
"wheel"
• ( A k : k>7 : P(k-1) P(k) )
Then we have proved: ( A n : n>=7 : P(n) )
Really? Can you prove me that, for instance, P(12) holds?
Answer: yes, I can ! ! !:
Start at the starting point and turn the wheel 5 times.
You see: P(12) is true.
3
And now: programming recursively
We need to implement a method. One of the parameters is an integer
which is greater than or equal to a "starting point".
Consider the functional proposition P:
P(n) : calling the method for value n for that integer parameter
(with n>= "starting point") does exactly what it is supposed to do.
If we implement the method correct, we have:
( A n : n>=starting point : P(n) )
One way of proving it, is by induction (recursion): prove
• P(starting point) is true, and
• ( A k : k>starting point : P(k-1) P(k) )
4
An example
The factorial of a non-negative integer n,
written as n! (pronounced "n factorial"),
is defined as the number of ways to arrange n different objects in a row.
Example: you have 5 objects.
Place them one by one in a row.
• For the first item you can choose out of 5 objects,
• for the second out of 4 objects,
• for the third out of 3 objects,
• etc.
The number of arrangements is 5*4*3*2*1,
so the answer is 120 possible arrangements.
5
The example about n factorial, continued
A recursive definition for n!:
• n! := 1 for n=0
• n! := n * (n-1)! for n>0
Assignment: implement a method to calculate
n factorial.
Solution:
public int fac(int n)
// for n>=0 the method returns n!
{
??????
}
6
The example about n factorial, continued
public int fac(int n)
// for n>=0 the method returns n!
{
return 1;
}
This implementation is correct for n=0.
public int fac(int n)
// for n>=0 the method returns n!
{
return n * fac(n-1);
}
If fac(n-1) does it correct, then this implementation
is correct for n.
7
The example about n factorial, continued
The former ideas combined:
public int fac(int n)
// for n>=0 the method returns n!
{
if (n == 0)
{
return 1;
}
else
{
return n * fac(n-1);
}
}
This implementation is correct for all n with n>=0.
8
Example: you want to calculate the sum of the first n integers
in an array.
public int getSum(int[] numbers, int n)
{
int sum = 0;
for ( int k = 0; k < n; k++)
{ sum = sum + numbers[k]; }
return sum;
}
or recursively:
public int getSum(int[] numbers, int n)
{
if ( n == 0 ) base case
{ return 0; }
else recursive call
{ return getSum(numbers, n-1) + numbers[n-1]; }
}
9
Example: array X: { 7, 3, 5, 9, 3, 6}
public int getSum(int[] numbers, int n)
{
if ( n == 0 ) { return 0; }
else { return getSum(numbers, n-1) + numbers[n-1]; }
}
a= a gets the value 10
getSum(X,2) ;
return getSum(X,1) + returns 7 + X[1], so returns
10
X[1];
returns 0 + X[0], so returns
return getSum(X,0) + 7
X[0];
return 0; returns 0
10
About a recursive method
• A recursive method is a method that calls itself.
• "Turning the wheel" should not continue forever:
in that chain of recursive calls you must reach a
"starting point" where the recursive calls stop.
• if "Turning the wheel" goes on forever, you get
troubles. At a certain moment all available
memory is occupied and you will get a "stack-
overflow-error".
11
Extra: towers of Hanoi
12
Hanoi, a difficult problem (if you don't like recursion)
3 piles (towers), numbered 1, 2, 3.
At startup: all discs are on pile 1 from "big to small".
At finish: all discs should be on pile 3.
A move: move a disc from one pile to another pile,
but you are not allowed to put a bigger disc on a smaller disc.
In how many moves can you solve the problem? And how should you
do it?
A solution without recursion: terrible to program.
A solution by using recursion: pretty simple.
13
Hanoi, a difficult problem (if you don't like recursion)
// Give me instructions about how to move
// nrOfDiscs discs from the pile numbered
// startPile to the pile numbered endPile.
// You may use the pile numbered helpingPile.
// Precondition: nrOfDiscs > 0.
public void Hanoi( int startPile,
int endPile,
int helpingPile,
int nrOfDiscs )
{
. . . // todo
}
Solution: next week.
14