Advanced Recursion

Post on 23-Feb-2016

35 views 0 download

Tags:

description

Advanced Recursion. Recursive Function Example: Factorial. Problem: calculate n! (n factorial) n! = 1 if n = 0 n! = 1 * 2 * 3 *...* n if n > 0 Recursively: if n = 0 , then n! = 1 if n > 0, then n! = n * ( n-1 ) !. Solving Recursive Problems. - PowerPoint PPT Presentation

Transcript of Advanced Recursion

Advanced Recursion

Recursive Function Example: Factorial

Problem: calculate n! (n factorial)n! = 1 if n = 0

n! = 1 * 2 * 3 *...* n if n > 0

Recursively:if n = 0, then n! = 1if n > 0, then n! = n * (n-1)!

Solving Recursive Problems

• See recursive solutions as two sections:– Current– Rest

N! = N * (N-1)!7! = 7 * 6! 7! = 7 * (6 * 5 * 4 * 3 * 2 * 1 * 1)

Factorial Function

function Factorial returnsa Num (n isoftype in Num)// Calculates n factorial, n! // Precondition: n is a non-negative// integer if (n = 0) then Factorial returns 1 else Factorial returns n * Factorial(n-1) endifendfunction //Factorial

if (0 = 0) then Fact returns 1 else Fact returns 1 endifendfunction //Fact

if (1 = 0) then Fact returns 1 else Fact returns 1 * Fact(0) endifendfunction //Factif (2 = 0)

then Fact returns 1 else Fact returns 2 * Fact(1) endifendfunction //Fact

if (3 = 0) then Fact returns 1 else Fact returns 3 * Fact(2) endifendfunction //Fact

algorithm Test ans <- Fact(3)endalgorithm

Tracing Details

function Fact returnsa Num (2) if (2 = 0) then Fact returns 1 else Fact returns 2 * Fact(1) endifendfunction //Fact

1. Actual parameters stored on the stack

2. Recursive call to Fact

4. Unfinished Business

3. Create a new Stack Frame

5. Return value and release stack frame

Activation Stack for Factorial

Call the function: answer <- Fact(5)

Main Algorithm: Unfinished: answer <- Fact (5)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 5th: N=1, Unfinished: 1*Fact(0)

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 5th: N=1, Unfinished: 1*Fact(0)

Fact. 6th: N=0, Finished: returns 1

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 5th: N=1, Finished: returns 1*1

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 4th: N=2, Finished: returns 2*1

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 3rd: N=3, Finished: returns 3*2

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Fact. 2nd: N=4, Finished: returns 4*6

Activation Stack for Factorial

Main Algorithm: Unfinished: answer <- Fact (5)

Fact. 1st: N=5, Finished: returns 5*24

Activation Stack for Factorial

Main Algorithm: Finished: answer <- 120

Exponentiation

baseexponent

e.g. 53

Could be written as a function

Power(base, exp)

LB

Can we write it recursively?

be = b * b(e-1)

What’s the limiting case?

When e = 0 we have b0 which always equals?

1

LB

Another Recursive Function

function Power returnsa Num (base, exp isoftype in Num)// Computes the value of BaseExp // Pre: exp is a non-negative integer if (exp = 0) then Power returns 1 else Power returns base * Power(base, exp-1) endifendfunction //Power

Function Power returnsa Num (base, exp isoftype in Num)//Computes the value of BaseExp

//Preconditions: exp is a non-negative integer if(exp = 0 ) then Power returns 1 else Power returns (base * Power(base, exp – 1)) endifendfunction //Power

Activations Stack Example

Algo: total <- Power(3,4)

Power base = 3 exp = 4 3 *Power(3,3)

Power base = 3 exp = 3 3 *Power(3,2)

Power base = 3 exp = 2 3 *Power(3,1)

Power base = 3 exp = 1 3 *Power(3,0)

Power base = 3 exp = 0 Finished: 1

Total <- 81

1

3

9

27

1

3

9

27

81

Bunnies?

• The Time: 13th Century• The Place: Italy• The Man: Fibonacci• The Problem: We start with a pair of newborn rabbits.

At the end of the 2nd month, and each month thereafter the female gives birth to a new pair of rabbits: one male and one female. The babies mature at the same rate as the parents and begin to produce offspring on the same schedule. So how many rabbits do we have at the end of one year?

LB

= 1 pair bunnies (m/f)LB

Fibonacci Number Sequence

if n = 1, then Fib(n) = 1if n = 2, then Fib(n) = 1if n > 2, then Fib(n) = Fib(n-2) + Fib(n-1)

Numbers in the series:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

A More Complex Recursive Function

Fibonacci Sequence Function

function Fib returnsa Num (n iot in Num)// Calculates the nth Fibonacci number // Precondition: N is a positive integer if ((n = 1) OR (n = 2)) then Fib returns 1 else Fib returns Fib(n-2) + Fib(n-1) endifendfunction //Fibonacci

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns Fib(1) + Fib(2)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(1): Fib returns 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + Fib(2)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + Fib(2)

Fib(2): Fib returns 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns Fib(2) + Fib(3)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns Fib(2) + Fib(3)

Fib(2): Fib returns 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns Fib(1) + Fib(2)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(1): Fib returns 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + Fib(2)

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + Fib(2)

Fib(2): Fib returns 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + 1

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + 2

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + 3

Tracing with Multiple Recursive Calls

Main Algorithm: answer <- 5

Mutual Recursion

Recursion doesn’t always occur because a routine calls itself...

Mutual Recursion occurs when two routines call each other.

A BB A

Mutual Recursion Example

Problem: Determine whether a number, N, is odd or even.

• If N is equal to 0, then n is even• N is odd if N-1 is even

Example Implementationfunction Odd returnsa Boolean (n iot in Num) if (n = 0) then Odd returns FALSE else Odd returns Even (n - 1) endifendfunction //Odd

function Even returnsa Boolean (n iot in Num) if (n = 0) then Even returns TRUE else Even returns Odd (n - 1) endifendfunction //Even

Building Recursive Modules• Decide on the terminating condition• Decide the final actions when you terminate

– There may be none– If you are computing something, this usually

starts a “ripple” of returned data• Decide how to take a step closer to terminating

– think about how to make your original, complex problem simpler

• Decide how to call a “clone” of this module• Decide what work to do at this step in recursion

Binary Search: Telephone Book

• Problem: Search the telephone book for someone’s phone number.

• Binary Search Strategy:a. Open the book somewhere near the middle.b. If the the person’s name is in the first half, ignore the

second half, and search the first half, starting again at step a).

c. If the the person’s name is in the second half, ignore the first half, and search the second half, starting again at step a).

d. If the person’s name is on a given page, scan the page for the person’s name, and find the phone number associated with it.

Binary Search: Search an Array• Problem: Given an array, A[ ], of n integers, sorted

from smallest to largest, determine whether value v is in the array.

• Binary Search Strategy:If n = 1 then check whether A[0] = v. Done.

Otherwise, find the midpoint of A[ ]. If v > A[midpoint] then recursively search the second

half of A[ ].If v <= A[midpoint] then recursively search the first half of A[ ].

Search an Array: Implementation

int binarySearch( int A[ ], int v, int first, int last ){ if( first > last ) return -1; // v not found in A[ ]

int mid = (first + last)/2; // set mid to midpoint

if(v == A[mid]) return mid; if(v < A[mid]) return binarySearch(A, v, first, mid-1 ); return binarySearch( A, v, mid+1, last );}

Implementation (2)

Two common mistakes:

1) CORRECT: mid = ( first + last )/2; INCORRECT: mid = ( A[first] + A[last] )/2;

2) CORRECT: return binarySearch( A, v, mid+1, last ); INCORRECT: return binarySearch( A, v, mid, last );

Search an Array: Implementation Notes

• The whole array, A[ ], is passed with each call to binarySearch( ).

• The active part of array A[ ] is defined by first and last.

• A return value of -1 means that v was not found.

Search an Array: Example• Suppose int A[ ] contains {1, 5, 9, 13, 17, 19, 23}, and

we are interested in searching for 19.• Executing binarySearch( A, 19, 0, 6 );

results in 0 1 2 3 4 5 6A 1 5 9 13 17 19 23

first lastmid

first mid last(found at mid!)

Search an Array: Example (Cont’d.)• Suppose we are interested in searching for 21:

1 5 9 13 17 19 23

first lastmid

first mid last

first, mid, last

last first(last before first!)

Search an Array: Final Comments

• Suppose that we have an array of a million numbers.• The first decision of a binary search will eliminate

approximately half of them, or 500,000 numbers.• The second decision will eliminate another 250,000.• Only 20 decisions are needed to determine whether a

given number is among a sorted list of 1 million numbers!

• A sequential search might have to examine all of them.

• Additional Note: Binary searching through a billion numbers would require about 30 decisions, and a trillion numbers would (theoretically) require only 40 decisions.

Famous Problem

• Greatest Common Divisor• Factorial

Questions?