112
Introduction to Computer Science Recursion The Runtime Stack Unit 15

Introduction to Computer Science Recursion The Runtime Stack Unit 15

  • View
    239

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Introduction to Computer Science

• Recursion

• The Runtime Stack

Unit 15Unit 15

Page 2: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 2

Recursion

• A method that calls itself is said to be recursive

• (Another formulation: A message that causes itself to be sent as another message)

• We have been looking a lot at loops: for, while, and do-while loops; recursion can be used as a substitute for loops, but it can do much more

• The ability to use recursion gives Java a lot of power, and gives us a new way of thinking about problem solutions

Page 3: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 3

Loop Example:Count Digits in "number"

numberOfDigits = 0;rest = number;do {

// The number of digits in number is// numberOfDigits plus the remaining// digits in restrest = rest / 10;numberOfDigits++;

} while (rest != 0);

Page 4: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 4

Recursion Example:Count Digits in "number"

Definition of digits(n):

1 if -9 n 9,digits(n) =

1 + digits(n/10) otherwise.

{

Page 5: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 5

Recursion Example:Count Digits in "number"

1 if -9 n 9,digits(n) =

1 + digits(n/10)otherwise.

{digits(321) = 1 + digits(321/10)

= 1 + digits(32)= 1 + (1 +

digits(32/10))= 1 + (1 + digits(3))= 1 + (1 + (1))= 3

Page 6: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 6

Recursive Definition

• A definition that is self-referential

• A definition that is defined in terms of simpler instances of itself

• It is not a "circular definition"; that would lead nowhere

• It is a "spiraling definition" that eventually terminates, and that must include a "base case", a final part of the definition that does not call itself

Page 7: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 7

Recursion Example:Count Digits in "number"

int numberOfDigits(int n) {if ( (-10 < n) && (n < 10) )

return 1;else

return (1 + numberOfDigits(n/10));}

Page 8: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 8

How to Write a Recursive Function, f(x)

• If you want to compute f(x), but can't do it directly–Assume you can compute f(y), for all

values y smaller than x

–Define f(x) in terms of f(y)

–Define the base case(s) — define f(x) directly (i.e., not in terms of f(y)) for some base value(s) of x

Page 9: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 9

Counting Digits Recursively, Again

int numberOfDigits(int n) {if ( (-10 < n) && (n < 10) )

return 1;else

return (1 + numberOfDigits(n/10));}

f(x)

Page 10: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 10

Counting Digits Recursively, Again

int numberOfDigits(int n) {if ( (-10 < n) && (n < 10) )

return 1;else

return (1 + numberOfDigits(n/10));}

1. We assume we can compute f(y) for y smaller

than x

f(x)

Page 11: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 11

Counting Digits Recursively, Again

int numberOfDigits(int n) {if ( (-10 < n) && (n < 10) )

return 1;else

return (1 + numberOfDigits(n/10));}

2. f(x) defined in terms of f(y), where y is smaller

than x

1. We assume we can compute f(y) for y smaller

than x

f(x)

Page 12: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 12

Counting Digits Recursively, Again

int numberOfDigits(int n) {if ( (-10 < n) && (n < 10) )

return 1;else

return (1 + numberOfDigits(n/10));}

2. f(x) defined in terms of f(y), where y is smaller

than x

1. We assume we can compute f(y) for y smaller

than x

f(x)

3. Define the base case for some x not in terms

of f(y)

Page 13: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 13

Another Example: factorial

int factorial(int n) {// Recursively multiply positive numbers// 1 through n

if ( (n == 0) || (n == 1) )return 1;

elsereturn ( n * factorial(n - 1) );

}

Page 14: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 14

Another Example: factorial

int factorial(int n) {// Recursively multiply positive numbers// 1 through n

if ( (n == 0) || (n == 1) )return 1;

elsereturn ( n * factorial(n - 1) );

}

f(x)

Page 15: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 15

Another Example: factorial

int factorial(int n) {// Recursively multiply positive numbers// 1 through n

if ( (n == 0) || (n == 1) )return 1;

elsereturn ( n * factorial(n - 1) );

}

1. We assume we can compute f(y) for y smaller

than x

f(x)

Page 16: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 16

Another Example: factorial

int factorial(int n) {// Recursively multiply positive numbers// 1 through n

if ( (n == 0) || (n == 1) )return 1;

elsereturn ( n * factorial(n - 1) );

}2. f(x) defined in terms of

f(y), where y is smaller than x

1. We assume we can compute f(y) for y smaller

than x

f(x)

Page 17: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 17

Another Example: factorial

int factorial(int n) {// Recursively multiply positive numbers// 1 through n

if ( (n == 0) || (n == 1) )return 1;

elsereturn ( n * factorial(n - 1) );

}2. f(x) defined in terms of

f(y), where y is smaller than x

1. We assume we can compute f(y) for y smaller

than x

f(x) 3. Define the base case for some x not in terms

of f(y)

Page 18: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 18

So What's Wrong with This?Recursive Definition of power( )

int power(int k, // number to be raised int n) { // power to which to raise

return ( k * power(k, n-1) );}

Compute kn

Right — missing the base case definition;this will go around in circles

Page 19: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 19

Recursive Definition of power( )

int power(int k, // number to be raised

int n) { // power to which to raise

if (n == 0)

return 1;

else

return ( k * power(k, n-1) );

}

Page 20: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 20

Recursive Definition of power( )

int power(int k, // number to be raised

int n) { // power to which to raise

if (n == 0)

return 1;

else

return ( k * power(k, n-1) );

}

f(x)

Page 21: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 21

Recursive Definition of power( )

int power(int k, // number to be raised

int n) { // power to which to raise

if (n == 0)

return 1;

else

return ( k * power(k, n-1) );

}

f(x)

1. We assume we can compute f(y) for y smaller

than x

Page 22: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 22

Recursive Definition of power( )

int power(int k, // number to be raised

int n) { // power to which to raise

if (n == 0)

return 1;

else

return ( k * power(k, n-1) );

}

f(x)

1. We assume we can compute f(y) for y smaller

than x

2. f(x) defined in terms of f(y), where y is smaller

than x

Page 23: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 23

Recursive Definition of power( )

int power(int k, // number to be raised

int n) { // power to which to raise

if (n == 0)

return 1;

else

return ( k * power(k, n-1) );

}

f(x)

1. We assume we can compute f(y) for y smaller

than x

2. f(x) defined in terms of f(y), where y is smaller

than x

3. Define the base case for some x not in terms

of f(y)

Page 24: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 24

What's the Point?

• We could write power( ) iteratively:

int power(int k, int n) {int result = 1;while (n > 0) {

result = result * k;n--;

}return result;

}

Page 25: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 25

Recursion Can Do Better

• Recursion does add overhead to a calculation

• Sometimes it is no better (or even worse) than iteration

• But recursion can also be better:–Recursion can give us a solution where

iteration would be much harder to define

– It can open up superior, more efficient solutions, for us

Page 26: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 26

New Definition of power( )

Consider a better, more efficient definition of power( ):

–If n is even, then kn is equal to (k(n/2))2

–If n is odd, then kn is equal tok*(k((n-1)/2))2

This leads to a divide and conquer algorithm; the method makes use of a problem half the size of the original

Page 27: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 27

New Definition of power( )

int power(int k, // number to be raised int n) { // power to which to raise

if (n == 0)return 1;

else {int t = power(k, n/2);if ( (n % 2) == 0 )

return (t * t);else

return ( k * t * t );}

}

Page 28: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 28

A Few Points on power( )

• t = power(k, n/2) works because integer division gives us n/2 if n is even, and (n-1)/2 if n is odd (just what we wanted)

• The first version of power( ) uses n multiplications to calculate the answer

• This version of power( ) uses log2 n multiplications, a much smaller number

• Again, recursion is not always more efficient• But recursion made the second version

natural

Page 29: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 29

Sometimes, the Recursive Call Appears More than Once

• A recursive method can call itself multiple times

• It works the same way:–Assume the recursive calls work

–Define the function in terms of the recursive calls

–Define the base case

Page 30: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 30

Another example: Fibonacci

if n is 1 or 2, the nth Fibonacci number is 1

if n is 3 or more, the nth Fibonacci number is the sum of the previous two Fibonacci numbers

Fibonacci sequence:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…

Page 31: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 31

The Recursive fibonacci( ) Definition

int fibonacci (int n) {// Recursively calculates Fibonacci number

if ( (n == 1) || (n == 2) ) return 1;else return ( fibonacci(n – 1) + fibonacci(n – 2) );

}

2. f(x) defined in terms of f(y), where y is smaller

than x

Page 32: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 32

Another Example: recursive definition of choose( ) function

• Compute binomial coefficients, "n choose

k", i.e., ( )• Given a set S of n distinct objects, for n ≥1, and a number 0 ≤k ≤n, how many subsets of S have exactly k elements?

• Example: Set S = {1, 2, 3}, k = 2; how many subsets of S have exactly 2 elements? "3 choose 2" is 3 (that is, {1, 2}, {1, 3}, {2, 3} ).

nk

Page 33: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 33

Recursion to the Rescue

• The solution would be much more difficult without recursion

• Assume we can calculate the function choose( ) for any values smaller than n and k

• Now define choose( ) in terms of choose( ) over smaller n's and k's…

Page 34: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 34

Pick out one element of S; call it a

• Every subset of S either includes a or it doesn't

• We can count the subsets by counting those with a, and counting those without a, and adding them up

• A k-element subset containing a is formed by choosing k - 1 elements from the remaining n - 1

elements of S, so there are ( ) such subsets

• A k-element subset that excludes a is formed by choosing k elements from the remaining n - 1

elements of S, so there are ( ) such subsets

n - 1k - 1

n - 1k

Page 35: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 35

Specific Example

• S = {1, 2, 3}, n = 3; k = 2; how many subsets of S have exactly 2 elements? "3 choose 2" is three (that is, {1, 2}, {1, 3}, {2, 3} )

• All these sets either include "1" or they don't

• Notice:

–Two of the sets include "1": {1, 2} and {1, 3}

–One of the sets doesn't include "1": {2, 3}

Page 36: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 36

Specific Example, continued

• We can figure out how many sets include "1" by pretending S is {2, 3}, and looking at "n-1 choose k-1" (that is, "2 choose 1"):

• There are two such sets: {2} and {3}

• These correspond to the "n choose k" (that is, "3 choose 2") sets that include "1", namely {1, 2} and {1, 3}

Page 37: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 37

Specific Example, continued

• We can figure out how many sets do not include "1" by pretending S is {2, 3}, and looking at "n - 1 choose k" (that is,"2 choose 2"):

• There is one such set: {2, 3}

• This corresponds to the "n choose k" (that is, "3 choose 2") set that doesn't include "1", namely {2, 3}

Page 38: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 38

Specific Example, finished

• Add up the number of sets that do include "1" (there are two) with the number of sets that do not include "1" (there is one), and you get the final answer: three

• "3 choose 2" defined in terms of–"2 choose 1" and–"2 choose 2"

• "n choose k" defined in terms of–"n - 1 choose k - 1" and–"n - 1 choose k"

Page 39: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 39

So Far, So Good

• But we are not done

• What about the base case(s)?

int choose(int n, int k) { return ( choose(n-1, k-1) + choose(n-1, k) );}

Page 40: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 40

The Base Cases

• It turns out that only two base cases are required, when k is 1, and when k is n

• When k is 1, then ( ) is n, because there are n 1-element subsets of an n-element set

• When k is n, then ( ) is 1, because there is 1 n-element subset of an n-element set

nk

nk

Page 41: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 41

Recursive Definition of choose( )

int choose(int n, int k) {if (k == 1)

return n;else if (k == n)

return 1;else

return ( choose(n-1, k-1)+ choose(n-1, k) );

}

Page 42: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 42

What's Happening in the Computer?

• The runtime stack, which plays an important role when one method sends a message to an object, is important for understanding what's happening with recursion, too

• A brief review…

Page 43: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 43

A Stack Handles Nesting

• Let’s improve the way we think about this nesting

• When method e calls method f( ), which calls method g( ), we can think of a “stack of methods”

• Like putting a piece of paper on top of another piece on top of another piece... the topmost piece is the method being executed now, the others we’ll return to

• Each piece of paper holds the parameters and local variables

Page 44: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 44

Starting Execution in main( )

Method main( )

STACK

public static void main (String[ ] args) {.........obj.e();...}

top

Page 45: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 45

Call to method e( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

Page 46: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 46

Executing method e( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

Page 47: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 47

Call to method f( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

Page 48: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 48

Executing method f( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

Page 49: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 49

Call to method g( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

Method g( )Where we came from: f, line 4

top

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Page 50: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 50

Method g( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

top

Page 51: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 51

Method f( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method e( )Where we came from: main, line 4

Method main( )

STACK

top

Page 52: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 52

Method e( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method main( )

STACK

top

Page 53: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 53

Variables are held on the stack, too

• When we put items on the stack, we also write down–values of parameters

– local variables

• Now, let's look at a recursive example, namely power( )

• The runtime stack keeps track of where we came from and where we'll return to

Page 54: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 54

Call to power(7, 5) from main( )

public static void main (String[ ] args) {

int x = power(7, 5);

}

Page 55: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 55

A reminder of power( ); parameters k and n; local variable t

int power(int k, // number to be raised int n) { // power to which to raise

if (n == 0)return 1;

else {int t = power(k, n/2);if ( (n % 2) == 0 )

return (t * t);else

return ( k * t * t );}

}

Page 56: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 56

Delayed Evaluation

• The recursive call to a method leaves partially evaluated expressions on the stack

• The recursive call typically occurs while an expression is being calculated. The stack delays the expression’s evaluation

• In this case, we'll delay the evaluation oft = power(k, n/2);

Page 57: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 57

The Runtime Stack (recursion)

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

STACK

top

int power(int k, // number to be raisedint n) { // power to which to raise

if (n == 0)return 1;

else {int t = power(k, n/2);if ( (n % 2) == 0 )

return (t * t);else

return ( k * t * t );}

}

Page 58: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 58

The Runtime Stack (recursion)

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

STACK

top

Method power( )Where we came from: power, line 6k: 7n: 2t: uninitialized

Page 59: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

STACK

top

Method power( )Where we came from: power, line 6k: 7n: 2t: uninitialized

Method power( )Where we came from: power, line 6k: 7n: 1t: uninitialized

Page 60: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

top

Method power( )Where we came from: power, line 6k: 7n: 2t: uninitialized

Method power( )Where we came from: power, line 6k: 7n: 1t: uninitialized

Method power( )Where we came from: power, line 6k: 7n: 0t: uninitialized

Page 61: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 61

n equal to zero causes power( ) to return 1, and sets t to returned value

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

Method power( )Where we came from: power, line 6k: 7n: 2t: uninitialized

Method power( )Where we came from: power, line 6k: 7n: 1t: 1

top

Page 62: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 62

Returning to power( ), line 7, we return k*t*t (i.e., 7) from line 10

Method power( )Where we came from: main, line …k: 7n: 5t: uninitializedMethod main( )

Method power( )Where we came from: power, line 6k: 7n: 2t: 7

top

STACK

Page 63: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 63

The value of n is 2, n%2 is 0, and we return t*t (i.e., 49) from line 8

Method power( )Where we came from: main, line …k: 7n: 5t: 49Method main( )

top

STACK

int power(int k, // number to be raisedint n) { // power to which to raise

if (n == 0)return 1;

else {int t = power(k, n/2);if ( (n % 2) == 0 )

return (t * t);else

return ( k * t * t );}

}

Page 64: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 64

Finally, power( ) sees that n is 5, n%2 is 1, and it returns k*t*t to main

Method main( )top

STACK

main( ) gets value

16,807

int power(int k, // number to be raisedint n) { // power to which to raise

if (n == 0)return 1;

else {int t = power(k, n/2);if ( (n % 2) == 0 )

return (t * t);else

return ( k * t * t );}

}

Page 65: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 65

What You’ve Seen,Recursively-speaking

• Simple recursive functions, f( )–numberOfDigits(n), uses 1 + f(n/10)

–factorial(n), uses n * f(n - 1)

–power(k, n), uses n * f(k, n - 1)

–Then a better power(k, n), using a divide and conquer approach

–fibonacci(n), using f(n - 1) + f(n - 2)

–choose(n, k), using f(n - 1, k - 1) + f(n - 1, k)

• The runtime stack for power(k, n)

Page 66: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 66

Another Example ofDelayed Evaluation

int sum (int n) {// Use recursion for addition of positive numbers.// Recursion is *not* the best way to do this…// It's just an example of delayed evaluation

if (n == 1)return 1;

else return ( n + sum(n - 1) );}

Page 67: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 67

Let’s say n is 5

Sum = 5 + Sum (5 – 1) // first Sum = 4 + Sum (4 – 1) // second

Sum = 3 + Sum (3 – 1) // third Sum = 2 + Sum (2 – 1) //fourth

Sum = 1 // fifth Sum = 1 // fifth Sum = 2 + 1 // fourth Sum = 3 + 3 // third

Sum = 4 + 6 // secondSum = 5 + 10 // first

return ( n + sum(n – 1) ) // unless n is 1

Page 68: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 68

Leaving Statements to be Executed

• Sometimes, as with power( ), there are statements left to execute in the recursive function, after the call to the next copy of itself is finished

• With power( ), after t got its value, there was still a calculation to be carried out before another value was returned

• Here’s another example…

Page 69: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 69

Print a Sentence in Reverse

class Recur { // Uses recursion to read a line and echo it in reverse

void stackTheCharacters( ) {char theCharacter;SimpleInput sinp = new SimpleInput(System.in);theCharacter = sinp.readChar( );

if (!sinp.eoln( ))stackTheCharacters( ); // The recursive call.

System.out.print(theCharacter);} // stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a sentence that is not a palindrome.”);

stackTheCharacters( ); //The first call.System.out.println( );}

} //Recur

Page 70: Introduction to Computer Science Recursion The Runtime Stack Unit 15

How does it work?

• When stackTheCharacters( ) is called, it reads a character value for its local variable theCharacter

• stackTheCharacters( ) is then called again, so…• The final statement of the first call, that is

System.out.print(theCharacter), is still waiting when the second call to stackTheCharacters( ) reads the next character

• Eventually we get back to finish the first call, and print theCharacter

Enter a sentence that is not a palindrome.Was that a Toyota I saw??was I atoyoT a taht saW

theCharacter = sinp.readChar( );if (!sinp.eoln( ))

stackTheCharacters( ); System.out.print(theCharacter);

Page 71: Introduction to Computer Science Recursion The Runtime Stack Unit 15

The Role of the Runtime Stack

TheRuntime

StackWas that a Toyota I saw?

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 72: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Remember where we arein main( )

Was that a Toyota I saw?

System.out.println( )

TheRuntime

Stack

theCharacter is ???

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 73: Introduction to Computer Science Recursion The Runtime Stack Unit 15

About to call stackTheCharacters( )

Was that a Toyota I saw?

System.out.println( )

TheRuntime

Stack

theCharacter is ‘W’

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 74: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Called stackTheCharacters( ) (again)

TheRuntime

StackWas that a Toyota I saw?

Syst...(theCharacter)theCharacter is ‘W’

theCharacter is ???

System.out.println( )

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 75: Introduction to Computer Science Recursion The Runtime Stack Unit 15

TheRuntime

StackWas that a Toyota I saw?

Called stackTheCharacters( ) (again2)

Syst...(theCharacter) theCharacter is ‘W’

theCharacter is ???Syst...(theCharacter) theCharacter is ‘a’

System.out.println( )

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 76: Introduction to Computer Science Recursion The Runtime Stack Unit 15

TheRuntime

StackWas that a Toyota I saw?

Called stackTheCharacters( ) (again3)

Syst...(theCharacter) theCharacter is ‘W’

theCharacter is ???

Syst...(theCharacter) theCharacter is ‘a’

Syst...(theCharacter) theCharacter is ‘s’

System.out.println( )

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 77: Introduction to Computer Science Recursion The Runtime Stack Unit 15

TheRuntime

StackWas that a Toyota I saw?

Called stackTheCharacters( ) (again24)

.

.

.

Syst...(theCharacter) theCharacter is ‘W’

theCharacter is ???

Syst...(theCharacter) theCharacter is ‘a’

Syst...(theCharacter) theCharacter is ‘w’

System.out.println( )

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 78: Introduction to Computer Science Recursion The Runtime Stack Unit 15

TheRuntime

StackWas that a Toyota I saw?

Print ‘?’, then finish executing the 23 interrupted instances of stackTheCharacters( )

.

.

.

Syst...(theCharacter) theCharacter is ‘W’

theCharacter is ‘?’

Syst...(theCharacter) theCharacter is ‘a’

Syst...(theCharacter) theCharacter is ‘w’

System.out.println( )

class Recur {void stackTheCharacters( ) {

char theCharacter;SimpleInput sinp = new

SimpleInput(System.in);theCharacter = sinp.readChar(

);if (!sinp.eoln( ))

stackTheCharacters( );System.out.print(theCharact

er);}// stackTheCharacters

public static void main (String[ ] args) {System.out.println(“Enter a

sentence that is not a palindrome.”);

stackTheCharacters( );System.out.println( );}

}

Page 79: Introduction to Computer Science Recursion The Runtime Stack Unit 15

Completing the (Interrupted) Methods (then System.out.println of the main block)

• theCharacter is ‘?’ and we execute System.out.print(‘?’)

Was that a Toyota I saw?

?

• theCharacter becomes ‘w’ and execute System.out.print(‘w’)?w

• theCharacter becomes ‘a’ and execute System.out.print(‘a’)?wa

• theCharacter becomes ‘W’ and execute System.out.print(‘W’)?was I atoyoT a taht saW

...

Page 80: Introduction to Computer Science Recursion The Runtime Stack Unit 15

TheRuntime

Stack

Class Recur {void stackTheCharacters24( ) {

theCharacter = sinp.readChar( );

System.out.print(theCharacter); }

void stackTheCharacters3( ) {theCharacter =

sinp.readChar( );stackTheCharacters4( );System.out.print(theCharact

er); }void stackTheCharacters2( ) {

theCharacter = sinp.readChar( );

stackTheCharacters3( );System.out.print(theCharact

er); }void stackTheCharacters1( ) {

theCharacter = sinp.readChar( );

stackTheCharacters2( );System.out.print(theCharact

er); }public static void main(String[ ]

args) {System.out.println(“Enter a

sentencethat is not a palindrome.”);

stackTheCharacters1( );System.out.println( ); }

} // Recur

Was that a Toyota I saw?

An “unfolded” way of looking at those 24 calls of stackTheCharacters( )

stackTheCharacters1

main

stackTheCharacters2

stackTheCharacters3

. . . ....

Syst...(theCharacter)theCharacter is ‘W’System.out.println( )

theCharacter is ‘?’

Syst...(theCharacter)theCharacter is ‘a’

Syst...(theCharacter)theCharacter is ‘s’

stackTheCharacters24

Page 81: Introduction to Computer Science Recursion The Runtime Stack Unit 15

The “unfolded” statementsthat are executed

System.out.println("Please enter a sentence.");theCharacter =sinp.readChar( ); //Reading in 'W' theCharacter = sinp.readChar( ); // Reading in 'a' theCharacter = sinp.readChar( ); // Reading in 's' theCharacter = sinp.readChar( ); // Reading in ' ' theCharacter = sinp.readChar( ); // Reading in 't' . . . . . // intermediate calls theCharacter = sinp.readChar( ); // Reading in 'w' theCharacter = sinp.readChar( ); // Reading in '?' System.out.print(theCharacter); // Printing the '?' System.out.print(theCharacter); // Printing the 'w' . . . . . // intermediate calls System.out.print(theCharacter); // Printing the 't' System.out.print(theCharacter); // Printing the ' ' System.out.print(theCharacter); // Printing the 's' System.out.print(theCharacter); // Printing the 'a'System.out.print(theCharacter); //Printing the 'W'System.out.println( ); // Last statement in main

Page 82: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 82

Tail Recursion

With tail, or end, recursion, there is nothing left to do after the last call. No unfinished statements have been left on the stack.

(The previous example, stackTheCharacters( ), was not an example of tail recursion because the System.out.print( ) call remained to be executed in each copy after the recursive call finished.)

Page 83: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 83

Specify the Recursive Procedure like a Loop

Goal: Print a positive integer in reverse.Stacking Plan: Print the ‘ones’ digit.Bound: There are no more digits to print.Unstacking Plan: —

Later we'll see another example where the Unstacking Plan is not empty.

Page 84: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 84

An Example of Tail Recursion

Class unDigit {// Recursively reverses the digits of a positive integervoid reverseDigits(int number) {

System.out.print(number % 10); if ( (number / 10) != 0 )

reverseDigits(number/10);}

public static void main (String[ ] args) {int num;SimpleInput sinp = new SimpleInput(System.in);System.out.print("Please enter positive

integer.");num = sinp.readInt( );reverseDigits(num);System.out.println( );

}}

Page 85: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 85

Tail Recursion is easilyre-written as an iterative loop

void iterativeReverse(int theNumber) {

do {

System.out.print(theNumber % 10);

theNumber = theNumber / 10;

} while (theNumber != 0) ;

}

Please enter a positive integer.2640770462

Page 86: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 86

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 87: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 87

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 88: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 88

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 89: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 89

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 90: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 90

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 91: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 91

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 92: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 92

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 93: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 93

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 94: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 94

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 95: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 95

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 96: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 96

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 97: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 97

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 98: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 98

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 99: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 99

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 100: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 100

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 101: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 101

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 102: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 102

The Towers of Hanoi

Move the entire stack from peg A to peg C, while obeying two rules:

1. Only one disk can be moved at a time.

2. A larger disk can never go on top of a smaller one.

Peg A Peg B Peg C

Page 103: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 103

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 104: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 104

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 105: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 105

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 106: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 106

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 107: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 107

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 108: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 108

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 109: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 109

The Recursive Solution

1. Move n – 1 disks from A to B.

2. Move 1 disk from A to C.

3. Move n – 1 disks from B to C.

Peg A Peg B Peg C

Page 110: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 110

The Recursive Specification

Goal: Solve the Tower of Hanoi problem for height n.

Stacking plan: Move n – 1 disks from fromPeg to usingPeg.

Bound: There’s just one disk left (it goes from fromPeg to toPeg).

Unstacking plan: Move n – 1 disks from usingPeg to toPeg.

We use the “other” peg as a temporary holder, and that peg’s identity keeps changing — so we’ll use fromPeg, toPeg, and usingPeg instead of A, B, C.

Page 111: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 111

The Java Method

void move (int height, fromPeg, toPeg, usingPeg) {// Recursive procedure for determining moves.// Keep this order—from, to, using—in mind when you// read the recursive calls.if ( height == 1 )

System.out.println("Move a disk from " + fromPeg + " to " + toPeg);

else {move(height – 1, fromPeg, usingPeg,

toPeg);System.out.println("Move a disk from " +

fromPeg + " to " + toPeg);move(height – 1, usingPeg, toPeg,

fromPeg);}

}

Page 112: Introduction to Computer Science Recursion The Runtime Stack Unit 15

15- 112

The Java Class

class Hanoi {

void move(int height, fromPeg, toPeg, usingPeg) {…}

public static void main (String[ ] args) { int height; SimpleInput sinp=new SimpleInput(System.in);

System.out.print("How many disks are yougoing to start with? ");

height = sinp.readInt( );move(height, 1, 3, 2);

}}