You are on page 1of 14

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

You might also like