JavaHTP6e 15 - user.engineering.uiowa.edu

28
1 2005 Pearson Education, Inc. All rights reserved. 15 15 Recursion

Transcript of JavaHTP6e 15 - user.engineering.uiowa.edu

Page 1: JavaHTP6e 15 - user.engineering.uiowa.edu

1

2005 Pearson Education, Inc. All rights reserved.

1515

Recursion

Page 2: JavaHTP6e 15 - user.engineering.uiowa.edu

2

2005 Pearson Education, Inc. All rights reserved.

OBJECTIVESIn this chapter you will learn:

The concept of recursion.How to write and use recursive methods.How to determine the base case and recursion step in a recursive algorithm.How recursive method calls are handled by the system.The differences between recursion and iteration, and when it is appropriate to use each.

Page 3: JavaHTP6e 15 - user.engineering.uiowa.edu

3

2005 Pearson Education, Inc. All rights reserved.

15.1 Introduction

• Earlier programs structured as methods that call one another in a disciplined, hierarchical manner

• Recursive methods– Call themselves– Useful for some problems to define a method to call itself– Can be called directly or indirectly through another

method

Page 4: JavaHTP6e 15 - user.engineering.uiowa.edu

4

2005 Pearson Education, Inc. All rights reserved.

15.2 Recursion Concepts

• Recursive problem-solving elements– Base case

• Recursive method capable of solving only simplest case—the base case• If method is called with base case, method returns result

– If method is called with more complex problem, problem divided into two pieces—a piece the method knows how to do and a piece the method does not know how to do (called recursive call or recursion step)

– Recursive call/recursion step• Must resemble original problem but be slightly simpler or smaller version• Method calls fresh copy of itself to work on smaller problem• Normally includes return statement

• Indirect recursion– Recursive method calls another method that eventually makes call back

to recursive method

Page 5: JavaHTP6e 15 - user.engineering.uiowa.edu

5

2005 Pearson Education, Inc. All rights reserved.

15.3 Example Using Recursion: Factorials

• Factorial of n, or n! is the productn · (n – 1) · (n – 2) · … · 1With 1! equal to 1 and 0! Defined to be 1.

• Can be solved recursively or iteratively (nonrecursively)• Recursive solution uses following relationship:

n! = n · (n – 1)!

• Infinite recursion – recursive calls are continuously made until memory has been exhausted

– Caused by either omitting base case or writing recursion step that does not converge on base case

Page 6: JavaHTP6e 15 - user.engineering.uiowa.edu

6

2005 Pearson Education, Inc. All rights reserved.

Fig. 15.2 | Recursive evaluation of 5!.

Page 7: JavaHTP6e 15 - user.engineering.uiowa.edu

7

2005 Pearson Education, Inc. All rights reserved.

Outline

Factorial

Calculator.java

1 // Fig. 15.3: FactorialCalculator.java 2 // Recursive factorial method. 3 4 public class FactorialCalculator

5 {

6 // recursive method factorial 7 public long factorial( long number )

8 {

9 if ( number <= 1 ) // test for base case 10 return 1; // base cases: 0! = 1 and 1! = 1 11 else // recursion step 12 return number * factorial( number - 1 ); 13 } // end method factorial 14 15 // output factorials for values 0-10 16 public void displayFactorials() 17 { 18 // calculate the factorials of 0 through 10 19 for ( int counter = 0; counter <= 10; counter++ ) 20 System.out.printf( "%d! = %d\n", counter, factorial( counter ) ); 21 } // end method displayFactorials 22 } // end class FactorialCalculator

Base case returns 1

Portion method knows how to do

Recursion step breaks problem into two parts: one the method knows how to do, one the method does not

Recursive call: Portion method does not know how to do; smaller version of original problem

Original call to recursive method

Page 8: JavaHTP6e 15 - user.engineering.uiowa.edu

8

2005 Pearson Education, Inc. All rights reserved.

Outline

FactorialTest.java

1 // Fig. 15.4: FactorialTest.java 2 // Testing the recursive factorial method. 3 4 public class FactorialTest

5 {

6 // calculate factorials of 0-10 7 public static void main( String args[] )

8 {

9 FactorialCalculator factorialCalculator = new FactorialCalculator();

10 factorialCalculator.displayFactorials(); 11 } // end main 12 } // end class FactorialTest 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800

Calculate and display factorials

Page 9: JavaHTP6e 15 - user.engineering.uiowa.edu

9

2005 Pearson Education, Inc. All rights reserved.

15.4 Example Using Recursion: Fibonacci Series

• Fibonacci series begins with 0 and 1 and has property that each subsequent Fibonacci number is the sum of previous two Fibonacci numbers.

• Series occurs in nature, ratio of successive Fibonacci numbers converges on golden ratio or golden mean

• Fibonacci series defined recursively as:fibonacci(0) = 0fibonacci(1) = 1fibonacci(n) = fibonacci(n – 1) + fibonacci(n – 2)

• Recursive solution for calculating Fibonacci values results in explosion of recursive method calls

Page 10: JavaHTP6e 15 - user.engineering.uiowa.edu

10

2005 Pearson Education, Inc. All rights reserved.

Outline

Fibonacci

Calculator.java

1 // Fig. 15.5: FibonacciCalculator.java 2 // Recursive fibonacci method. 3 4 public class FibonacciCalculator

5 {

6 // recursive declaration of method fibonacci 7 public long fibonacci( long number )

8 {

9 if ( ( number == 0 ) || ( number == 1 ) ) // base cases 10 return number; 11 else // recursion step 12 return fibonacci( number - 1 ) + fibonacci( number - 2 ); 13 } // end method fibonacci 14 15 public void displayFibonacci() 16 { 17 for ( int counter = 0; counter <= 10; counter++ ) 18 System.out.printf( "Fibonacci of %d is: %d\n", counter, 19 fibonacci( counter ) ); 20 } // end method displayFibonacci 21 } // end class FibonacciCalculator

Two base cases

Two recursive calls

Original call to recursive method

Page 11: JavaHTP6e 15 - user.engineering.uiowa.edu

11

2005 Pearson Education, Inc. All rights reserved.

Outline

FibonacciTest.java

1 // Fig. 15.6: FibonacciTest.java 2 // Testing the recursive fibonacci method. 3 4 public class FibonacciTest

5 {

6 public static void main( String args[] )

7 {

8 FibonacciCalculator fibonacciCalculator = new FibonacciCalculator();

9 fibonacciCalculator.displayFibonacci();

10 } // end main 11 } // end class FibonacciTest Fibonacci of 0 is: 0 Fibonacci of 1 is: 1 Fibonacci of 2 is: 1 Fibonacci of 3 is: 2 Fibonacci of 4 is: 3 Fibonacci of 5 is: 5 Fibonacci of 6 is: 8 Fibonacci of 7 is: 13 Fibonacci of 8 is: 21 Fibonacci of 9 is: 34 Fibonacci of 10 is: 55

Calculate and display Fibonacci values

Page 12: JavaHTP6e 15 - user.engineering.uiowa.edu

12

2005 Pearson Education, Inc. All rights reserved.

Fig. 15.7 | Set of recursive calls for fibonacci( 3 ).

Page 13: JavaHTP6e 15 - user.engineering.uiowa.edu

13

2005 Pearson Education, Inc. All rights reserved.

15.5 Recursion and the Method Call Stack

• Method call stack used to keep track of method calls and local variables within a method call

• Just as with nonrecursive programming, recursive method calls are placed at the top of the method call stack

• As recursive method calls return, their activation records are popped off the stack and the previous recursive calls continue executing

• Current method executing is always method whose activation record is at top of stack

Page 14: JavaHTP6e 15 - user.engineering.uiowa.edu

14

2005 Pearson Education, Inc. All rights reserved.

15.6 Recursion vs. Iteration

• Any problem that can be solved recursively can be solved iteratively

• Both iteration and recursion use a control statement– Iteration uses a repetition statement– Recursion uses a selection statement

• Iteration and recursion both involve a termination test– Iteration terminates when the loop-continuation condition fails– Recursion terminates when a base case is reached

• Recursion can be expensive in terms of processor time and memory space, but usually provides a more intuitive solution

Page 15: JavaHTP6e 15 - user.engineering.uiowa.edu

15

2005 Pearson Education, Inc. All rights reserved.

Software Engineering Observation 15.1

Any problem that can be solved recursively can also be solved iteratively (nonrecursively). A recursive approach is normally preferred over an iterative approach when the recursive approach more naturally mirrors the problem and results in a program that is easier to understand and debug. A recursive approach can often be implemented with fewer lines of code. Another reason to choose a recursive approach is that an iterative one might not be apparent.

Page 16: JavaHTP6e 15 - user.engineering.uiowa.edu

16

2005 Pearson Education, Inc. All rights reserved.

Outline

Factorial

Calculator.java

1 // Fig. 15.10: FactorialCalculator.java 2 // Iterative factorial method. 3 4 public class FactorialCalculator

5 {

6 // recursive declaration of method factorial 7 public long factorial( long number )

8 {

9 long result = 1;

10 11 // iterative declaration of method factorial 12 for ( long i = number; i >= 1; i-- ) 13 result *= i; 14 15 return result; 16 } // end method factorial 17 18 // output factorials for values 0-10 19 public void displayFactorials() 20 { 21 // calculate the factorials of 0 through 10 22 for ( int counter = 0; counter <= 10; counter++ ) 23 System.out.printf( "%d! = %d\n", counter, factorial( counter ) ); 24 } // end method displayFactorials 25 } // end class FactorialCalculator

Iterative solution uses counter-controlled repetition

Page 17: JavaHTP6e 15 - user.engineering.uiowa.edu

17

2005 Pearson Education, Inc. All rights reserved.

Outline

FactorialTest.java

1 // Fig. 15.11: FactorialTest.java 2 // Testing the iterative factorial method. 3 4 public class FactorialTest

5 {

6 // calculate factorials of 0-10 7 public static void main( String args[] )

8 {

9 FactorialCalculator factorialCalculator = new FactorialCalculator();

10 factorialCalculator.displayFactorials(); 11 } // end main 12 } // end class FactorialTest 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800

Page 18: JavaHTP6e 15 - user.engineering.uiowa.edu

18

2005 Pearson Education, Inc. All rights reserved.

Avoid using recursion in situations requiring high performance. Recursive calls take time and consume additional memory.

Performance Tip 15.2

Page 19: JavaHTP6e 15 - user.engineering.uiowa.edu

19

2005 Pearson Education, Inc. All rights reserved.

15.7 String Permutations

• Permutations of a string of text – all the different strings that can be created by rearranging characters of original string

• Words created from permutations are known as anagrams

• Recursive solution: Remove one character, find permutations of remaining characters (recursive case), combine permutations with character that was removed

• Base case: Finding permutations for just one character –character itself is the only permutation

• Any string provides n! permutations for n characters

Page 20: JavaHTP6e 15 - user.engineering.uiowa.edu

20

2005 Pearson Education, Inc. All rights reserved.

Outline

Permutation.java

(1 of 2)

1 // Fig. 15.12: Permutation.java 2 // Recursive method to find all permutations of a String. 3 4 public class Permutation

5 {

6 // recursive declaration of method permuteString 7 private void permuteString(

8 String beginningString, String endingString )

9 {

10 // base case: if string to permute is length less than or equal to 11 // 1, just display this string concatenated with beginningString 12 if ( endingString.length() <= 1 ) 13 System.out.println( beginningString + endingString ); 14 else // recursion step: permute endingString 15 { 16 // for each character in endingString 17 for ( int i = 0; i < endingString.length(); i++ ) 18 { 19 try 20 { 21 // create new string to permute by eliminating the 22 // character at index i 23 String newString = endingString.substring( 0, i ) + 24 endingString.substring( i + 1 ); 25

Base case: Combine removed characters (beginningString) with

endingString, which is only one character

Remove one character; We will find permutations for remaining characters

Page 21: JavaHTP6e 15 - user.engineering.uiowa.edu

21

2005 Pearson Education, Inc. All rights reserved.

Outline

Permutation.java

(2 of 2)

26 // recursive call with a new string to permute 27 // and a beginning string to concatenate, which 28 // includes the character at index i 29 permuteString( beginningString + 30 endingString.charAt( i ), newString ); 31 } // end try 32 catch ( StringIndexOutOfBoundsException exception ) 33 { 34 exception.printStackTrace(); 35 } // end catch 36 } // end for 37 } // end else 38 } // end method permuteString 39 } // end class Permutation

Recursive call: find permutations for remaining characters then reattach

removed characters

Page 22: JavaHTP6e 15 - user.engineering.uiowa.edu

22

2005 Pearson Education, Inc. All rights reserved.

Outline

PermutationTest .java

(1 of 2)

1 // Fig. 15.13: PermutationTest.java 2 // Testing the recursive method to permute strings. 3 import java.util.Scanner;

4 5 public class PermutationTest

6 {

7 public static void main( String args[] )

8 {

9 Scanner scanner = new Scanner( System.in );

10 Permutation permutationObject = new Permutation(); 11 12 System.out.print( "Enter a string: " ); 13 String input = scanner.nextLine(); // retrieve String to permute 14 15 // permute String 16 permutationObject.permuteString( "", input ); 17 } // end main 18 } // end class PermutationTest

Initial call to recursive method; There are no removed characters yet, so

first argument is “”

Page 23: JavaHTP6e 15 - user.engineering.uiowa.edu

23

2005 Pearson Education, Inc. All rights reserved.

Outline

PermutationTest

.java

(2 of 2)

math

maht

mtah

mtha

mhat

mhta

amth

amht

atmh

athm

ahmt

ahtm

tmah

tmha

tamh

tahm

thma

tham

hmat

hmta

hamt

hatm

htma

htam

Page 24: JavaHTP6e 15 - user.engineering.uiowa.edu

24

2005 Pearson Education, Inc. All rights reserved.

15.8 Towers of Hanoi

• Classic problem – Priests in Far East are attempting to move a stack of disks from one peg to another. One disk must be moved at a time, at no time may a larger disk be placed above a smaller disk

• Recursive solution:– Move n – 1 disks from peg 1 to peg 2, using peg 3 as temporary

holding area– Move the last disk (the largest) from peg 1 to peg 3– Move the n – 1 disks from peg 2 to peg 3, using peg 1 as a

temporary holding area• Base case: When only one disk needs to be moved – no

temporary holding area needed, disk is simply moved

Page 25: JavaHTP6e 15 - user.engineering.uiowa.edu

25

2005 Pearson Education, Inc. All rights reserved.

Fig. 15.14 | Towers of Hanoi for the case with four disks.

Page 26: JavaHTP6e 15 - user.engineering.uiowa.edu

26

2005 Pearson Education, Inc. All rights reserved.

15.9 Fractals

• Fractal – a geometric figure that often can be generated from a pattern repeated recursively an infinite number of times

• Pattern applied to each segment of original figure• Benoit Mandelbrot introduced term “fractal,”

along with specifics of how fractals are created and their practical applications

– Help us better understand patterns in nature, the human body and the universe

– Popular art form

Page 27: JavaHTP6e 15 - user.engineering.uiowa.edu

27

2005 Pearson Education, Inc. All rights reserved.

15.9 Fractals

• Self-similar property – fractals have this property in the case that, when subdivided into parts, each resembles a reduced-size copy of the whole

• If part is exact copy of original, fractal is said to be strictly self similar

• Each time pattern is applied, fractal is said to be at new level or depth

• Fractal examples: Koch Curve, Koch Snowflake

Page 28: JavaHTP6e 15 - user.engineering.uiowa.edu

28

2005 Pearson Education, Inc. All rights reserved.

Fig. 15.17 | Koch Curve fractal.

(a) (b)

(c) (d)

(e) (f)