recursion chapter 8. 2 chapter contents what is recursion? tracing a recursive method recursive...

36
Recursion Chapter 8

Post on 19-Dec-2015

242 views

Category:

Documents


0 download

TRANSCRIPT

Recursion

Chapter 8

2

Chapter Contents

What Is Recursion?

Tracing a Recursive Method

Recursive Methods That Return a Value

Recursively Processing an Array

Recursively Processing a Linked Chain

The Time Efficiency of Recursive Methods• Time Efficiency of countDown

A Simple Solution to a Difficult Problem

A Poor Solution to a Simple Problem

3

What Is Recursion?

It is a problem-solving process involves repetitionBreaks a problem into identical but smaller problemsEventually you reach a smallest problem• Answer is obvious or trivial

Using the solution to smallest problem enables you to solve the previous smaller problemsEventually the original big problem is solvedAn alternative to iteration

• An iterative solution involves loops

4

What Is Recursion?

New Year Eve: counting down from 10.

5

What Is Recursion?

A method that calls itself is a recursive method

• Base case: a known case in a recursive definition. The smallest problem

• Eventually, one of the smaller problems must be the base case

/** Task: Counts down from a given positive integer.* @param integer an integer > 0 */

public static void countDown(int integer)

{ System.out.println(integer);if (integer > 1)

countDown(integer - 1);} // end countDown

6

When Designing Recursive Solution

Four questions to ask before construct recursive solutions. If you follow these guidelines, you can be assured that it will work. • How can you define the problem in terms of a smaller

problem of the same type?• How does each recursive call diminish the size of the

problem?• What instance of the problem can serve as the base

case?• As the problem size diminishes, will you reach this

base case?

7

When Designing Recursive Solution

For the method countDown, we have the following answers.• countDown displays the given integer as the

part of the solution that it contribute directly. Then call countDown with smaller size.

• The smaller problem is counting down from integer -1.

• The if statement asks if the process has reached the base case. Here, the base case occurs when integer is 1.

8

Recursive Solution GuidelinesMethod definition must provide parameter• Leads to different cases• Typically includes an if or a switch

statement

One or more of these cases should provide a non recursive solution( infinite recursion if don’t)• The base or stopping case

One or more cases includes recursive invocation• Takes a step towards the base case

9

Tracing a Recursive Method

Given: public static void countDown(int integer)

{ System.out.println(integer);if (integer > 1)

countDown(integer - 1);} // end countDown

The effect of method call countDown(3)

10

Tracing a Recursive Method

Tracing the recursive call countDown(3)

11

Compare Iterative and Recursive Programs

//Recursive version

public static void countDown( int integer)

{

if ( integer >= 1)

{

System.out.println(integer);

countDown(integer -1);

}

}

//Iterative version

public static void countDown( int integer)

{

while ( integer >= 1)

{

System.out.println(integer);

integer--;

}

}

12

Question?

Could you write an recursive method that skips n lines of output, where n is a positive integer. Use System.out.println() to skip one line.

Describe a recursive algorithm that draws a given number of concentric circles. The innermost or outmost circle should have a given diameter. The diameter of each of the other circles should be three-fourths the diameter of the circle just outside it.

13

Answer to skipLines

pubic static void skipLines ( int givenNumber)

{

if (givenNumber >= 1)

{

System.out.println();

skipLines(givenNumber – 1);

}

}

drawConcentricCircle( givenNumber, givenDiameter)

{

// what should be put inside??…….

}

14

Tracing a Recursive Method

Each call to a method generate an activation record that captures the state of the method’s execution and that is placed into a ADT stack. The activation-record stack remembers the history of incompleted method calls. A snapshot of a method’s state. The topmost activation record holds the data values for the currently executing method. When topmost method finishes, its activation record is popped In this way, Java can suspend the execution of a recursive method and re-invoke it when it appears on the top.

15

Tracing a Recursive Method

The stack of activation records during the execution of a call to countDown(3)… continued →

16

Tracing a Recursive Method

ctd. The stack of activation records during the execution of a call to countDown(3)

Note: the recursive method will use more

memory than an iterative method due

to the stack of activation records

Note: the recursive method will use more

memory than an iterative method due

to the stack of activation records

17

Tracing a Recursive Method

Too many recursive calls can cause the error message “stack overflow”. Stack of activation records has become full. Method has used too much memory.

Infinite recursion or large-size problems are the likely cause of this error.

18

Recursive Methods That Return a Value

Task: Compute the sum1 + 2 + 3 + … + n for an integer n > 0

public static int sumOf(int n){ int sum;

if (n = = 1)sum = 1; // base case

elsesum = sumOf(n - 1) + n; // recursive call

return sum;} // end sumOf

19

Recursive Methods That Return a Value

The stack of activation records during the execution of a call to sumOf(3)

20

Recursively Processing an Array

When processing array recursively, divide it into two pieces• Last element one piece, rest of array another• First element one piece, rest of array another• Divide array into two halves

A recursive method part of an implementation of an ADT is often private• Its necessary parameters make it unsuitable as an

ADT operation

21

Recursively Processing a Linked Chain

To write a method that processes a chain of linked nodes recursively• Use a reference to the chain's first node as the

method's parameter

Then process the first node• Followed by the

rest of the chain

public void display(){ displayChain(firstNode);

System.out.println();} // end display

private void displayChain(Node nodeOne)

{ if (nodeOne != null){ System.out.print(nodeOne.data + " ");

displayChain(nodeOne.next);}

} // end displayChain

22

Recursively Divide the Array in Halfpublic static void displayArray( int array[], int first, int last)

{

if (first == last)

System.out.print(array[first]);

else

{

int mid = (first + last) /2;

displayArray(array, first, mid);

displayArray(array, mid+1, last);

}

}

23

A Simple Solution to a Difficult Problem

The initial configuration of the Towers of Hanoi for three disks

24

A Simple Solution to a Difficult Problem

Rules for the Towers of Hanoi game

1. Move one disk at a time. Each disk you move must be a topmost disk.

2. No disk may rest on top of a disk smaller than itself.

3. You can store disks on the second pole temporarily, as long as you observe the previous two rules.

25

A Simple Solution to a Difficult Problem

The sequence of moves for solving the Towers of Hanoi problem with three

disks.

Continued →

26

A Simple Solution to a Difficult Problem

(ctd) The sequence of moves for solving the

Towers of Hanoi problem with three disks

27

A Simple Solution to a Difficult Problem

The smaller problems in a recursive solution for

four disks

28

A Simple Solution to a Difficult Problem

Algorithm for solution with 1 disk as the base case

Algorithm solveTowers(numberOfDisks, startPole, tempPole, endPole)

if (numberOfDisks == 1)

Move disk from startPole to endPole

else

{

solveTowers(numberOfDisks-1, startPole, endPole, tempPole)

Move disk from startPole to endPole

solveTowers(numberOfDisks-1, tempPole, startPole, endPole)

}

29

Recursion Efficiency

How many moves occur for n disks?

m(1) = 1 for n>1, two recursive calls to solve problems that have n-1 disks.

m(n) = m(n-1) + m(n-1) +1 = 2*m(n-1) +1

Let’s evaluate the recurrence for m(n) for a few values of n:

m(1) =1; m(2) = 3; m(3) = 7;m(4) = 15; m(5) = 31; m(6) = 63….

m(n) = 2^n -1

30

Mathematical Induction

Prove this conjecture m(n) = 2^n -1 by using mathematical induction:

We know that m(1) =1, which equals to 2^1-1=1, so the conjecture is true for n =1.

Now assume that it is true for n=1,2,…,k, and consider m(k+1).

m(k+1) = 2*m(k) +1 (use the recurrence relation)

=2*(2^k-1) +1 = 2^(k+1) -1 ( we assume that m(k) = 2^k-1)

Since the conjecture is true for n=k+1, it is true for all n>=1

31

Mathematical Induction

Assume you want to prove some statement P, P(n) is true for all n starting with n = 1. The Principle of Math Induction states that, to this end, one should accomplish just two steps:1). Prove that P(1) is true. 2). Assume that P(k) is true for some k. Derive from here that P(k+1) is also true.

look P(1) is true and implies P(2). Therefore P(2) is true. But P(2) implies P(3). Therefore P(3) is true which implies P(4) and so on.

32

Multiplying Rabbits (The Fibonacci Sequence)

“Facts” about rabbits• Rabbits never die• A rabbit reaches sexual maturity exactly two

months after birth, that is, at the beginning of its third month of life

• Rabbits are always born in male-female pairs• At the beginning of every month, each

sexually mature male-female pair gives birth to exactly one male-female pair

33

Multiplying Rabbits (The Fibonacci Sequence)

Problem• How many pairs of rabbits are alive in month n?• Month Month No calculation rabbit couples • January 1 1 + 0 = 1• February 2 1 + 0 = 1• March 3 1 + 1 = 2• April 4 2 + 1 = 3• May 5 3 + 2 = 5• June 6 5 + 3 = 8• July 7 8 + 5 = 13• August 8 13 + 8 = 21

Recurrence relationrabbit(n) = rabbit(n-1) + rabbit(n-2)

34

A Poor Solution to a Simple Problem

Fibonacci numbers• First two numbers of sequence are 1 and 1• Successive numbers are the sum of the

previous two• 1, 1, 2, 3, 5, 8, 13, …

This has a natural looking recursive solution• Turns out to be a poor (inefficient) solution

35

A Poor Solution to a Simple Problem

The recursive algorithm

Algorithm Fibonacci(n)if (n <= 1)

return 1else

return Fibonacci(n-1) + Fibonacci(n-2)

36

A Poor Solution to a Simple Problem

The computation of the Fibonacci number F6 (a) recursively; (b) iteratively

Time efficiency grows exponentially with n,

which is k^n

Time efficiency grows exponentially with n,

which is k^n

Iterative solution is O(n)Iterative solution is O(n)

int fib(int n) { int f[n+1]; f[1] = f[2] = 1; for (int i = 3; i <= n; i++) f[i] = f[i-1] + f[i-2]; return f[n]; }