You are on page 1of 25

Week 12: Recursion

1. 2.

Recursion is natural
Many natural phenomena are recursion
A smaller part of oneself is embedded in itself

(a)

Tree

(b)

Infinite mirror images (c) dominos


2

Sometimes,

it is easier to solve a given problem using recursion

Ex. 1: The handshake problem


Question: There are n people in the room. If each person shakes hands once with every other person, what will the total number of handshakes be?
A B A
A

B
C

A
A

B A
C B

D
D

B
Two persons

C C
Four persons

D
3

Three persons

Ex. 1: The handshake problem (contd)


There is a trick to know the total number
If there are two persons, only one handshake If there are three persons, treat it as having one more person added to the two persons, and shakes hands with them (2 extra handshakes) If there are four persons, treat it as having one more person added to the three persons, and shakes hands with them (3 extra handshakes)

We can generalize the total number into a formula:


h(2) = 1 h(3) = h(2) + 2
h(4) = h(3) + 3

h(n) = h(n-1) + (n-1) if n >= 2 h(n) = 0 otherwise

The handshake function


The skeleton code
int handshake(int n) { /* 1. The base case when n <= 1*/ /* 2. The general case */ }

The handshake function


It solves the basic case
When n<=1, return 0 (no one to shake)
int handshake(int n) { if ( n <= 1 ) return 0; // no one to shake

The handshake function


The general case
a method calling itself
int handshake(int n) { if ( n <= 1 ) return 0; // no one to shake else return handshake(n-1) + n-1; }

Ex. 2: Factorial function


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!

Ex. 2: 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)

Factorial function
The Java equivalent of this definition
a method calling itself
int fac(int number) { if (number <= 1) return 1; else return number * fac(number-1); }

10

Factorial function
Assume the number n is 3, that is, number=3.
fac(3) : 3 <= 1 ? No fac(3) = 3 * fac(2) fac(2) : 2 <= 1 ? fac(2) = 2 * fac(1)

No

fac(1) : 1 <= 1 ? Yes return 11 fac(2) = 2 * 11= 2 return 2 fac(3) = 3 * 2 = 6 return 6 fac(3) has the value 6
11

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 number){ int fac(int number){ int product=1; if (number<=1) while (number>1){ return 1; product = product*number; else number--; return number*fac(number-1); } }
return product; }
12

Recursion
However, 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!)
13

Caution with iterations


If we use iteration, we must be careful not to create an infinite loop by accident:
for(int incr=1; incr!=10; incr+=2) ... int result = 1; while(result > 0){ ... result++; }

Oops!

Oops!
14

Caution with recursions


Similarly, if we use recursion we must be careful not to create an infinite chain of function calls:
int fac(int number){ return number * fac(number-1); } No terminating condition
int fac(int number){ if(number <= 1) return 1; Oops! else return number * fac(number+1); }
15

Recursion
We must always make sure that the recursion:
A recursive function must contain at least one non-recursive branch The recursive calls must eventually lead to a non-recursive branch

16

Recursion
Recursion is one way to decompose a task into smaller subtasks At least one of the subtasks is a simpler example of the same task
The smallest example of the same task has a non-recursive solution

An example is the factorial function


n! = n * (n-1)! 1! = 1 (simpler subtask is (n-1)!) (the simplest example is n=1)
17

How many pairs of rabbits can be produced from a single pair in a year's time?
Assumptions:
Each new pair of rabbits becomes fertile at the age of one month; Each pair of fertile rabbits produces a new pair of offspring every month; None of the rabbits dies in that year.

Example:
Initially, God creates a pair of rabbits; After 1 month, the pair of rabbits become fertile; After 2 months, there will be 2 pairs of rabbits; After 3 months, there will be 3 pairs; After 4 months, there will be 5 pairs (since the following month the original pair and the pair born during the first month will both produce a new pair and there will be 5 in all).
18

Population growth in nature


Leonardo Pisano (Leonardo Fibonacci = Leonardo, son of Bonaccio) proposed the sequence in 1202 in The Book of the Abacus. Fibonacci numbers are believed to model nature to a certain extent, such as Kepler's observation of leaves and flowers in 1611. creation

19

Direct Computation Method


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 (Fibonacci number at 0th position)

F(1) = 1

(Fibonacci number at 1st position)

F(number) = F(number-1)+ F(number-2)


20

Ex. 3: Fibonacci numbers


n
static int fibon(int n) { if (n == 0) return 0; if (n == 1) return 1; return (fibon(n-1) + fibon(n-2)); } public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter the value n: "); int n = input.nextInt(); int nRabbits = fibon(n); System.out.print("The number of pairs " + "of rabbits after " + n + " month(s) is equal " + "to " + nRabbits + " pair(s)" ) ; }

Pairs
creation 0 1 1 2 3 5

0 1

2
3 4 5

The program asks for an integer, then prints the Fibonacci number at that position
21

Copyright 2000 by Brooks/Cole Publishing Company A division of International Thomson Publishing Inc.

Intermediate steps to calculate the 4th Fibonacci number (i.e. n=4)


Calculating F(4) using recursion
Many intermediate steps are re-calculated (underlined items)
F(4) F(3) F(2)

F(2)
F(1) F(0)

F(1)

F(1)

F(0)

23

Summary
How to write recursively?
Begin with non-recursive branches, then recursive ones int recursive_fn(parameters){ //the non-recursive branch(s) if (stopping condition) return stopping value; //other stopping conditions if needed //the recursive branch(s) (calling itself) return function of recursive_fn(revised parameters) }
24

Summary
We have briefly introduced three examples (both can be solved by using either a loop or recursion) Sometimes, a problem is more intuitive to solve using recursion

25

You might also like