Chapter 32 Slides

129

description

Exposure Java-AB 2007. Chapter 32 Slides. Recursion II. PowerPoint Presentation created by: Mr. John L. M. Schram. From Materials Created by Mr. Leon Schram. Important Note. The end of the APCS1 course included a healthy chapter on recursion. - PowerPoint PPT Presentation

Transcript of Chapter 32 Slides

Page 1: Chapter 32 Slides
Page 2: Chapter 32 Slides

Important NoteThe end of the APCS1 course included a healthy chapter on recursion.

It is entirely possible that you did not make it to that chapter or perhaps there was not sufficient time to do the topic justice.

It is also possible that plenty of time was devoted to recursion, but summer activities took their toll on your memory.

For these reasons this chapter will first review the earlier, first-year course chapter and then continue with additional advanced recursion concepts.

Keep in mind that it is not possible to do certain advanced topics

in the AB course without a thorough knowledge of recursion.

Page 3: Chapter 32 Slides

Recursion DefinitionRecursion is the computer programming process, whereby a method calls itself.

Page 4: Chapter 32 Slides

Recursion is an important topic with frequent questions on both the A and the AB APCS Examination.

The A Examination requires that a student can understand and evaluate recursive methods.

The A Examination does not require that students generate free response recursive solutions.

The AB Examination does require that students generate some free response recursive solutions.

APCS Exam Alert

Page 5: Chapter 32 Slides

The Grid ProblemAn image can be represented as a grid of black and white cells.

Two cells in an image are part of the same object if each is black and there is a sequence of moves from one cell to the other, where each move is either horizontal or vertical to an adjacent black cell.

For example, the diagram below represents an image that contains four separate objects, one of them consisting of a single cell.

1

Page 6: Chapter 32 Slides

Recursion Requires an ExitThe original BASIC programming language makes frequent use of the GOTO control structure.

GOTO is very much frowned upon by computer scientists who do not like to see unconditional jumps in a program.

100 REM Program that counts integers starting at 0110 K = 0120 K = K + 1130 PRINT K140 GOTO 120

Page 7: Chapter 32 Slides

// Java3201.java// This program demonstrates recursion without an exit.// The recursive calls will continue until the program aborts // with an error message.

public class Java3201{ static int k = 0; public static void main(String args[]) {

count(); } public static void count() {

k++;System.out.print(k + " ");count();

}}

Page 8: Chapter 32 Slides

// Java3202.java// This program demonstrates how to add an exit or base case to control recursive callspublic class Java3202{ static int k = 0; public static void main(String args[]) {

System.out.println("CALLING ITERATIVE COUNT METHOD");count1();System.out.println("\n\nCALLING RECURSIVE COUNT METHOD");count2();System.out.println("\n\nEXECUTION TERMINATED");

} public static void count1() /***** ITERATIVE COUNT *****/ {

for (int k = 1; k <= 100; k++) System.out.print(k + " ");

} public static void count2() /***** RECURSIVE COUNT *****/ {

k++;System.out.print(k + " ");

if (k < 100) count2(); } }

Page 9: Chapter 32 Slides

Important Recursion Rule

All recursive methods must have an exit that stops the recursive process.

The special case or condition that stops the recursive calls is called the base case.

Page 10: Chapter 32 Slides

// Java3203.java This program demonstrates the <Skip> method.public class Java3203{ public static void main(String args[]) {

System.out.println("CALLING ITERATIVE SKIP METHOD");skip1(4);System.out.println("CALLING RECURSIVE SKIP METHOD");skip2(3);System.out.println("EXECUTION TERMINATED");

} public static void skip1(int n) /***** ITERATIVE SKIP *****/ {

for (int k = 1; k <= n; k++) System.out.println();

} public static void skip2(int n) /***** RECURSIVE SKIP *****/ {

if ( n > 0){

System.out.println(); skip2(n-1);}

}}

Page 11: Chapter 32 Slides

// Java3204.java// This program demonstrates the <count(a,b)> method, which displays // consecutive integers from a to b.public class Java3204{ public static void main(String args[]) {

System.out.println("CALLING ITERATIVE COUNT METHOD");count1(10,25);System.out.println("\n\nCALLING RECURSIVE COUNT METHOD");count2(26,40);System.out.println("\n\nEXECUTION TERMINATED");

} public static void count1(int a, int b) /***** ITERATIVE COUNT *****/ {

for (int k = a; k <= b; k++) System.out.print(k + " ");

} public static void count2(int a, int b) /***** RECURSIVE COUNT *****/ {

if (a <= b){

System.out.print(a + " "); count2(a+1,b);

} }}

Page 12: Chapter 32 Slides

// Java3205.java// This program compares the difference between "post-recursive" calls and "pre-recursive" calls.public class Java3205{ public static void main(String args[]) {

System.out.println("CALLING POST-RECURSIVE COUNT METHOD");count1(100,200);System.out.println("\n\nCALLING PRE-RECURSIVE COUNT METHOD");count2(100,200);System.out.println("\n\nEXECUTION TERMINATED");

} public static void count1(int a, int b) /**** POST-RECURSIVE COUNT ****/ {

if (a <= b){ System.out.print(a + " ");

count1(a+1,b);}

} public static void count2(int a, int b) /**** PRE-RECURSIVE COUNT ****/ {

if (a <= b){

count2(a+1,b); System.out.print(a + " ");

} }}

Page 13: Chapter 32 Slides

The Internal Stack & RecursionJava has a special internal data structure, called a stack that is hidden from the programmer.

A stack is a data structure that will only access data from one end, usually called the top, in such a manner that it behaves like a LIFO.

Data is accessed Last In, First Out.

Program execution sequence is handled by something called an Index Pointer.

The Index Pointer, or IP for short, contains the next memory address of the line to be executed.

NOTE: An IP, which points to a memory address in a computer is in no way related to an Internet Protocol (IP) Address on the internet.

Page 14: Chapter 32 Slides

// Java3206.java// This program demonstrates how recursion can display output in reverse order.

public class Java3206{

public static void main(String args[]){

System.out.println("\n\nCALLING PRE-RECURSIVE COUNT METHOD");count2(100,105);System.out.println("\n\nEXECUTION TERMINATED");

} public static void count2(int a, int b)

{if (a <= b){

System.out.println("Interrupting method completion; pushing " + a + " on stack.");

count2(a+1,b);System.out.println("Returning to complete method; popping " + a

+ " from stack.");System.out.println("Displaying popped value " + a);

}}

}

Page 15: Chapter 32 Slides

Fundamental Recursion Concepts

All recursive methods require an or base case that stops the recursive process.

The stack controls recursion, since it controls the execution sequence of methods, and stores local method information.

Every method call requires the completion of the called method, even if the execution sequence is interrupted by another recursive method call.

Incomplete recursive calls result in a LIFO execution sequence.

Page 16: Chapter 32 Slides

// Java3207.java This program demonstrates the <sum> method.// It also demonstrates recursion with return methods.public class Java3207{ public static void main(String args[]) { System.out.println("CALLING ITERATIVE SUM METHOD"); System.out.println("1 + 2 + 3 + 4 + 5 + 6 = " + sum1(6)); System.out.println("\n\nCALLING RECURSIVE SUM METHOD"); System.out.println("1 + 2 + ... + 99 + 100 = " + sum2(100)); System.out.println("\n\nEXECUTION TERMINATED"); }

public static int sum1(int n) /***** ITERATIVE SUM *****/ { int sum = 0; for (int k = 1; k <= n; k++) sum += k; return sum; }

public static int sum2(int n) /***** RECURSIVE SUM *****/ { if (n == 0) return 0; else return n + sum2(n-1); }}

Page 17: Chapter 32 Slides

Stepping Through the Recursive Process with sum2(4)

CALL # n Method sum2 returns

12345

43210

4 + Sum2(3)3 + Sum2(2)2 + Sum2(1)1 + Sum2(0)0

sum2(4) = 4 + 3 + 2 + 1 + 0 = 10

Page 18: Chapter 32 Slides

// Java3208.java // This program demonstrates the <fact> method.public class Java3208{

public static void main(String args[]){

System.out.println("CALLING ITERATIVE FACTORIAL METHOD");System.out.println("6 Factorial = " + fact1(6));System.out.println("\n\nCALLING RECURSIVE FACTORIAL METHOD");System.out.println("7 Factorial = " + fact2(7));System.out.println("\n\nEXECUTION TERMINATED");

}public static int fact1(int n) /***** ITERATIVE FACT *****/{

int temp = 1;for (int k = n; k > 0; k--)

temp *= k; return temp;

}public static int fact2(int n) /***** RECURSIVE FACT *****/{

if (n == 0)return 1;

elsereturn n * fact2(n-1);

}} Doesn’t this look like the mathematical definition of factorial?

Page 19: Chapter 32 Slides

Stepping Through the Recursive Process with fact2(6)

CALL # n Method fact2 returns

1

2

3

4

5

6

7

6

5

4

3

2

1

0

6 * Fact2(5)

5 * Fact2(4)

4 * Fact2(3)

3 * Fact2(2)

2 * Fact2(1)

1 * Fact2(0)

1

sum2(4) = 6 * 5 * 4 * 3 * 2 * 1 * 1 = 720

Page 20: Chapter 32 Slides

// Java3209.java This program demonstrates the <gcf> method.public class Java3209{

public static void main(String args[]){

System.out.println("CALLING ITERATIVE GCF METHOD");System.out.println("GCF of 120 and 108 is " + gcf1(120,108));System.out.println("\n\nCALLING RECURSIVE GCF METHOD");System.out.println("GCF of 360 and 200 is " + gcf2(360,200));System.out.println("\n\nEXECUTION TERMINATED");

}public static int gcf1(int n1, int n2) /***** ITERATIVE GCF *****/{

int temp = 0; int rem = 0;do{

rem = n1 % n2;if (rem == 0) temp = n2;else{

n1 = n2;n2 = rem;

}} while (rem != 0);return temp;

}

Page 21: Chapter 32 Slides

Stepping Through the Recursive Process with gcf2(360,200)

public static int gcf2(int n1, int n2){

int rem = n1 % n2;if (rem == 0)

return n2;else

return gcf2(n2,rem);}

CALL# n1 n2 rem Method gcf2 returns

1

2

3

360

200

160

200

160

40

160

40

0

gcf2(200,160)

gcf2(160,40)

40

gcf2(360,200) = 40

Page 22: Chapter 32 Slides

Fibonacci, a Recursive No-No

The Fibonacci Sequence is a sequence of numbers that is formed by the sum of the two previous numbers in the sequence.

The sequence starts with two ones, and from that point on, each number is formed by adding the two previous numbers.

1 2 3 4 5 6 7 8 9 10 11 12 13 14

1 1 2 3 5 8 13 21 34 55 89 144 233 377

Page 23: Chapter 32 Slides

// Java3210.java// This program demonstrates the <fibo> method. Note that this style of recursion becomes // unacceptibly slow when the requested Fibonacci number becomes larger.

import java.util.*;

public class Java3210{

public static void main(String args[]) {

Scanner input = new Scanner(System.in);System.out.print("Enter requested Fibonacci number ===>> ");int number = input.nextInt();System.out.println("\n\nCALLING ITERATIVE FIBO METHOD");System.out.println("Fibonacci(" + number + ") is " + fibo1(number));System.out.println("\n\nCALLING RECURSIVE FIBO METHOD");System.out.println("Fibonacci(" + number + ") is " + fibo2(number));System.out.println("\n\nEXECUTION TERMINATED");

}

Page 24: Chapter 32 Slides

/***** ITERATIVE FIBO *****/

public static int fibo1(int n){

int n1 = 1;int n2 = 1;int n3 = 1;if (n == 1 || n == 2)

return 1;else{

for (int k = 3; k <= n; k++){

n3 = n1 + n2;n1 = n2;n2 = n3;

}}return n3;

}

Page 25: Chapter 32 Slides

/***** RECURSIVE FIBO *****/

public static int fibo2(int n){

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

elsereturn fibo2(n-1) + fibo2(n-2);

} The problem with the recursive solution can be seen when you view how quickly the timeto compute the Fibo numbers increases:Fibo# Time Fibo# Time41 3 seconds 51 1 hour42 6 seconds 58 4½ days43 12 seconds 61 1 month

44 24 seconds 81 1,000,000 months

Page 26: Chapter 32 Slides

Fibonacci Problem Explained9

The diagram is only for the 9th Fibonacci number. You see the large number of recursive calls, and you can also see how many times the same computation is performed.

Page 27: Chapter 32 Slides

Recursion Warning

Avoid recursive methods that have a single program statement with multiple recursive calls, like the Fibonacci Sequence:

return fibo(n-1) + fibo(n-2);

Page 28: Chapter 32 Slides
Page 29: Chapter 32 Slides

APCS Exam Alert

Evaluating recursive methods, like the examples that follow will be required for both the A and AB multiple choice part of the examination.

Few students are comfortable with this type of problem at the first introduction.

Most students achieve excellent evaluation skills with repeated practice.

Page 30: Chapter 32 Slides

Exercise 01Determine that m1(5) == 25.

public int m1(int n){ if (n == 1) return 25; else return m1(n-1);}

CALL # n Method m1 returns

12345

54321

m1(4)m1(3)m1(2)m1(1)25

m1(5) == 25

25 is returnedno matter what N is

as long as N >= 1

Page 31: Chapter 32 Slides

Exercise 02Determine that m2(5) causes an error.

public int m2(int n){ if (n == 1) return 25; else return m2(n+1);}

CALL # n Method m2 returns

1234

5678

m2(6)m2(7)m2(8)m2(9)

Error results because the base case cannot be reached.

It is not possible for N to ever reach 1.

The function recursively calls itself until the

computer's stack runs out of memory.

Page 32: Chapter 32 Slides

Exercise 03Determine that m3(5) == 39.

public int m3(int n){ if (n == 1) return 25; else return n + m3(n-1);}

CALL # n Method m3 returns

12345

54321

5 + m3(4)4 + m3(3)3 + m3(2)2 + m3(1)25

m3(5) == 5 + 4 + 3 + 2 + 25 == 39

Page 33: Chapter 32 Slides

Exercise 04Determine that m4(1) == 10. public int m4(int n){ if (n == 5) return 0; else return n + m4(n+1);}

CALL # n Method m4 returns

12345

12345

1 + m4(2)2 + m4(3)3 + m4(4)4 + m4(5)0

m4(1) == 1 + 2 + 3 + 4 + 0 = = 10

Page 34: Chapter 32 Slides

Exercise 05Determine that m5(6) == 38

public int m5(int n){ if (n == 1 || n == 0) return 0; else return n + m5(n-1) + m5(n-2);}

CALL # n Method m5 returns

123456

654321

6 + m5(5) + m5(4)5 + m5(4) + m5(3)4 + m5(3) + m5(2)3 + m5(2) + m5(1)2 + m5(1) + m5(0)0

m5(6) == 6 + 5 + 4 + 3 +2 + 0 == 20 ???

What?

Page 35: Chapter 32 Slides

Since anything less than 2 will return 0, we only add the numbers that are 2 or

over. Now we have 6 + 5 + 4 + 4 + 3 + 3 + 2 + 3

+ 2 + 2 + 2 + 2 = 38

Exercise 05 Explained

Page 36: Chapter 32 Slides

Exercise 06Determine that m6(5) == 120

public int m6(int n){ if (n == 1) return 1; else return n * m6(n-1);}

CALL # n Method m6 returns

12345

54321

5 * m6(4) 4 * m6(3) 3 * m6(2) 2 * m6(1) 1

m6(5) == 1 * 2 * 3 * 4 * 5 == 120

This is a recursive factorial function.

Page 37: Chapter 32 Slides

Exercise 07Determine that m7(5,6) == 30

public int m7(int a, int b){ if (a == 0) return 0; else return b + m7(a-1,b);}

CALL # a b Method m7 returns

123456

543210

666666

6 + m7(4,6)6 + m7(3,6)6 + m7(2,6)6 + m7(1,6)6 + m7(0,6)0

m7(5,6) = 6 + 6 + 6 + 6 + 6 + 0 = 30

This is a recursive way to multiply 2 numbers.

(Not that you would ever want to do it this way!)

Page 38: Chapter 32 Slides

Exercise 08Determine that m8(4,3) == 81

public int m8(int a, int b){ if (a == 0) return 1; else return b * m8(a-1,b);}

CALL # a b Method m8 returns

12345

43210

33333

3 * m8(3,3)3 * m8(2,3)3 * m8(1,3)3 * m8(0,3)1

m8(4,3) == 3 * 3 * 3 * 3 * 1 == 81

This is a recursive power function.It computes BA.

Page 39: Chapter 32 Slides

Exercise 09Determine that m9(4,3) == 64

public int m9(int a, int b){ if (b == 0) return 1; else return a * m9(a,b-1);}

CALL # a b Method m9 returns

1234

4444

3210

4 * m9(4,2)4 * m9(4,1)4 * m9(4,0)1

m9(4,3) == 4 * 4 * 4 * 1 == 64

This is also a recursive power

function.But, it computes AB.

Page 40: Chapter 32 Slides

Exercise 10Determine that m10(7,3) == 17

public int m10(int a, int b){ if (a < b) return 5; else return b + m10(a-1,b+1);}

CALL # a b Method m10 returns

1234

7654

3456

3 + m10(6,4)4 + m10(5,5)5 + m10(4,6)5

m10(7,3) == 3 + 4 + 5 + 5 == 17

Page 41: Chapter 32 Slides

// Java3211.java// This program demonstrates the <linear> method, which performs a Linear Search of a sorted array.

public class Java3211{

public static void main(String args[]){

int list[] = new int[100];assign(list);display(list); System.out.println("\n\nCALLING ITERATIVE LINEAR SEARCH METHOD");System.out.println("Number 425 is located at index " + linear1(list,425));System.out.println("Number 211 is located at index " + linear1(list,211)); System.out.println("\n\nCALLING RECURSIVE LINEAR SEARCH METHOD");System.out.println("Number 375 is located at index " + linear2(list,375,0));System.out.println("Number 533 is located at index " + linear2(list,533,0));System.out.println("\n\nEXECUTION TERMINATED");

}public static void assign(int list[]){

for (int k = 0; k < list.length; k++)list[k] = 100 + k * 5;

}public static void display(int list[]){

for (int k = 0; k < list.length; k++)System.out.print(list[k] + " ");

}

Page 42: Chapter 32 Slides

/***** ITERATIVE LINEAR SEARCH *****/

public static int linear1(int list[], int key){

boolean found = false;int k = 0;while (k < list.length && !found){

if (list[k] == key)found = true;

elsek++;

}if (found)

return k; else

return -1;}

First, we need to review the LinearSearch method, implemented iteratively.

This implementation of the search algorithm returns the index (k) of the search item (key), or it returns k == -1 if the search is not successful.

Page 43: Chapter 32 Slides

/***** RECURSIVE LINEAR SEARCH *****/

public static int linear2(int list[], int key, int k){

if (k == list.length)return -1;

elseif (list[k] == key)

return k;else

return linear2(list,key,k+1);}

Page 44: Chapter 32 Slides
Page 45: Chapter 32 Slides

// Java3212.java

// This program demonstrates the <binary> method, which performs

// a Binary Search of a sorted array.

public class Java3212

{

public static void main(String args[])

{

int list[] = new int[100];

assign(list);

display(list);

System.out.println("\n\nCALLING ITERATIVE BINARY SEARCH METHOD");

System.out.println("Number 425 is at index " + binary1(list,425));

System.out.println("Number 211 is at index " + binary1(list,211));

System.out.println("\n\nCALLING RECURSIVE BINARY SEARCH METHOD");

System.out.println("Number 375 is at index " + binary2(list,375,0,99));

System.out.println("Number 533 is at index " + binary2(list,533,0,99));

System.out.println("\n\nEXECUTION TERMINATED");

}

Page 46: Chapter 32 Slides

/***** ITERATIVE BINARY SEARCH *****/public static int binary1(int list[], int key){

int lo = 0; int hi = list.length-1; int mid = 0;boolean found = false;while (lo <= hi && !found){

mid = (lo + hi) /2;if (list[mid] == key)

found = true;else

if (key > list[mid])lo = mid + 1;

elsehi = mid - 1;

}if (found)

return mid; else

return -1;}

Page 47: Chapter 32 Slides

/***** RECURSIVE BINARY SEARCH *****/public static int binary2(int list[], int key, int lo, int hi){

int mid = 0;if (lo > hi)

return -1;else{

mid = (lo + hi) /2;if (list[mid] == key)

return mid;else

if (key > list[mid])return binary2(list,key,mid+1,hi);

elsereturn binary2(list,key,lo,mid-1);

}}

Page 48: Chapter 32 Slides
Page 49: Chapter 32 Slides

Recursion and ParametersChanging existing iterative methods into recursive methods is an excellent exercise in obtaining proficiency with recursion.

Frequently it may be necessary to add parameters to the headings of the recursive methods.

Two examples of methods that require additional parameters in the recursive implementation are the Linear Search and the Binary Search.

Page 50: Chapter 32 Slides
Page 51: Chapter 32 Slides

Multiple Recursive Calls and The Tower of Hanoi

Towers of Hanoi at the Start of the 5-Disk Problem

5

4

3

2

1

Peg A Peg B Peg C

Page 52: Chapter 32 Slides

Multiple Recursive Calls and The Tower of Hanoi

5

4

3

2

1

Peg A Peg B Peg C

Towers of Hanoi at the End of the 5-Disk Problem

Page 53: Chapter 32 Slides

The Trivial One-Disk Problem

Let us look at a variety of problems, starting with the simplest possible situation. Suppose that you only need to move one disk from peg A to peg C. Would that be any kind of problem?

1

Peg A Peg B Peg C

Page 54: Chapter 32 Slides

The Trivial One-Disk Problem

How do we solve the 1-Disk problem? In exactly one step that be described with the single statement:

Move Disk1 from Peg A to Peg C

1

Peg A Peg B Peg C

Page 55: Chapter 32 Slides

The Easy Two-Disk Problem

Start

Peg A Peg B Peg C

2

1

Page 56: Chapter 32 Slides

The Easy Two-Disk Problem

Step 1

Peg A Peg B Peg C

2 1

Page 57: Chapter 32 Slides

The Easy Two-Disk Problem

Step 2

Peg A Peg B Peg C

21

Page 58: Chapter 32 Slides

The Easy Two-Disk Problem

Step 3 - Finished

Peg A Peg B Peg C

2

1

Page 59: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Start

Page 60: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 1

Page 61: Chapter 32 Slides

5

4

3

2 1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 2

Page 62: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 3

Page 63: Chapter 32 Slides

5

4

32

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 4

Page 64: Chapter 32 Slides

5

4

32

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 5

Page 65: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 6

Page 66: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 7

Page 67: Chapter 32 Slides

5 4 3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 8

Page 68: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4 3

21

Peg A Peg B Peg C

Step 9

Page 69: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4 3

2 1

Peg A Peg B Peg C

Step 10

Page 70: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4 3

2

1

Peg A Peg B Peg C

Step 11

Page 71: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4

32

1

Peg A Peg B Peg C

Step 12

Page 72: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4

32

1

Peg A Peg B Peg C

Step 13

Page 73: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4

3

2

1

Peg A Peg B Peg C

Step 14

Page 74: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5 4

3

2

1

Peg A Peg B Peg C

Step 15

Page 75: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

54

3

2

1

Peg A Peg B Peg C

Step 16

Page 76: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

54

3

2

1

Peg A Peg B Peg C

Step 17

Page 77: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

54

3 2

1

Peg A Peg B Peg C

Step 18

Page 78: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

54

3 2

1

Peg A Peg B Peg C

Step 32

Page 79: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

543

2

1

Peg A Peg B Peg C

Step 20

Page 80: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

543

21

Peg A Peg B Peg C

Step 21

Page 81: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

543

2 1

Peg A Peg B Peg C

Step 22

Page 82: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

543

2

1

Peg A Peg B Peg C

Step 23

Page 83: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3

2

1

Peg A Peg B Peg C

Step 24

Page 84: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3

2

1

Peg A Peg B Peg C

Step 25

Page 85: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3 2

1

Peg A Peg B Peg C

Step 26

Page 86: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3 2

1

Peg A Peg B Peg C

Step 27

Page 87: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3

2

1

Peg A Peg B Peg C

Step 28

Page 88: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3

21

Peg A Peg B Peg C

Step 29

Page 89: Chapter 32 Slides

The Tower of Hanoi5 Disk Demo

5

4

3

2

1

Peg A Peg B Peg C

Step 30

Page 90: Chapter 32 Slides

5

4

3

2

1

Peg A Peg B Peg C

The Tower of Hanoi5 Disk Demo

Step 31 - Finished

Page 91: Chapter 32 Slides

Tower of Hanoi FormulaThere is a pattern in the number of minimum moves to solve a given Tower of Hanoi problem.

With n the number of disks to be moved, the formula below computes the number or required moves.

2n - 1

Page 92: Chapter 32 Slides

// Java3213.java This program solves the "Tower of Hanoi" puzzle.import java.util.*;public class Java3213{

public static void main(String args[]) {

Scanner input = new Scanner(System.in); System.out.print("\nHow many disks are in the tower ===>> ");

int disks = input.nextInt();solveHanoi('A','B','C',disks);System.out.println("\n\nEXECUTION TERMINATED");

}

public static void solveHanoi(char s, char t, char d, int n)// s - source peg t - temporary peg d - destination peg n - number of disks{

if (n != 0){

solveHanoi(s,d,t,n-1);System.out.println("Move Disk "+n+" From Peg "+ s + " to Peg " + d);solveHanoi(t,s,d,n-1);

}}

} YES! That’s it!

Page 93: Chapter 32 Slides
Page 94: Chapter 32 Slides

Tower of HanioGeneral Solution

Move n-1 disks from Source Peg to Auxiliary Peg

Move the nth disk from Source Peg to Destination Peg

Move n-1 disks from Auxiliary Peg to Destination Peg

Page 95: Chapter 32 Slides

Tower of Hanoi Formula

Towers of Hanoi at Start of N-Disk Problem

N

N - 1

N - 2

2

1

Peg A Peg B Peg C

Page 96: Chapter 32 Slides

Tower of Hanoi Formula

Move N-1 Disks from Peg A to Peg B

N N - 1

N - 2

2

1

Peg A Peg B Peg C

Page 97: Chapter 32 Slides

Tower of Hanoi Formula

Move Nth Disk from Peg A to Peg C

NN - 1

N - 2

2

1

Peg A Peg B Peg C

Page 98: Chapter 32 Slides

Tower of Hanoi Formula

Move N-1 Disks from Peg B to Peg C

N

N - 1

N - 2

2

1

Peg A Peg B Peg C

Page 99: Chapter 32 Slides

Why Recursion?

Recursion is preferred over iteration when it is easier to write program code recursively.

Page 100: Chapter 32 Slides
Page 101: Chapter 32 Slides

The Grid Problem RevisitedComplete method alterGrid using the header below, such that all cells in the same object as grid[row][col] are set to white; otherwise grid is unchanged.

grid is a two-dimensional array of boolean elements.

An element value of true means a black cell and an element value of false means a white cell.

1

public void alterGrid(boolean grid[][], int row, int col)

Page 102: Chapter 32 Slides

// Java3214.java // Recursive solution to the black/white "Grid" problempublic static void alter(boolean grid[][], int r, int c){

if ((r >= 1) && (r <= 10) && (c >= 1) && (c <= 10))if (grid[r][c]){

grid[r][c] = false;alter(grid,r-1,c);alter(grid,r+1,c);alter(grid,r,c-1);alter(grid,r,c+1);

}}

Page 103: Chapter 32 Slides

Java3214.java Output #1

Enter row value ===>> 1Enter col value ===>> 1

O X X O X X O X O XO O X O X O O X X OX O O X X O X X O XO O O O X O O O X XO X O X X O O O X XO O X X O X X X O XO X X O O O O X X XX X O O X O O X O OO O O X X X X X O XO X O O O O X O O X

O X X O X X O X O XO O X O X O O X X OX O O X X O X X O XO O O O X O O O X XO X O X X O O O X XO O X X O X X X O XO X X O O O O X X XX X O O X O O X O OO O O X X X X X O XO X O O O O X O O X

Since there is no “object” located at index [1][1],

no change is made to the grid.

NOTE:This program does

not use row 0 or column 0.

Page 104: Chapter 32 Slides

Java3214.java Output #2

Enter row value ===>> 2Enter col value ===>> 2

X X X O X X O X X XX X O O X X O X X OX O O O O O O X X OO O O O O O X O X XX X X X X X X X O XO X O X O X O O O XX O O X O O X O O OO O X O O O O X O XO O O X X X O X O OX X O O X X X O X O

O O O O X X O X X XO O O O X X O X X OO O O O O O O X X OO O O O O O X O X XX X X X X X X X O XO X O X O X O O O XX O O X O O X O O OO O X O O O O X O XO O O X X X O X O OX X O O X X X O X O

public static void alter(boolean grid[][], int r, int c)

{if ((r >= 1) && (r <= 10) &&

(c >= 1) && (c <= 10))if (grid[r][c]){

grid[r][c] = false;alter(grid,r-1,c);alter(grid,r+1,c);alter(grid,r,c-1);alter(grid,r,c+1);

}}

Page 105: Chapter 32 Slides

Java3214.java Output #3

Enter row value ===>> 5Enter col value ===>> 5

X X X O X X X X X OO X O X X O O X X XX O X X X X O O O OO O O O X O X O X OO X O X X X X X X OX O O X X O X O X OX X O O O X O O X XO X O X O X O X X OX X X O X O X O X OX O X X X O O O X O

X X X O O O O O O OO X O O O O O O O OX O O O O O O O O OO O O O O O O O O OO X O O O O O O O OX O O O O O O O O OX X O O O X O O O OO X O X O X O O O OX X X O X O X O O OX O X X X O O O O O

public static void alter(boolean grid[][], int r, int c)

{if ((r >= 1) && (r <= 10) &&

(c >= 1) && (c <= 10))if (grid[r][c]){

grid[r][c] = false;alter(grid,r-1,c);alter(grid,r+1,c);alter(grid,r,c-1);alter(grid,r,c+1);

}}

Page 106: Chapter 32 Slides

Something to think about…

The solution to the grid problem uses the same algorithm as a “floadfill” in a paint program.

Extra Credit

Write a program that solves the grid problem

ITERATIVELY.

Page 107: Chapter 32 Slides

Original Recursion I Conclusion

This concludes the recursion concepts that were first presented in Chapter XIX. You will find that it is the bigger part of the entire chapter.

The next sections will move on to the additional Recursion II material. Make sure that you are comfortable with the first part of recursion before you move on.

Recursion is a powerful tool in computer science that can confuse people in the beginning. You will probably find that reading the chapter several times, listening to the lectures, and doing the program assignments will start more and more recursive lights burning upstairs.

Page 108: Chapter 32 Slides
Page 109: Chapter 32 Slides

Bubble Sort and RecursionPlease do not think that recursion is recommended for the Bubble Sort algorithm.

This section investigates some special situations that occur with nested loops that are converted to recursion.

The Bubble Sort is a short, easy to understand, algorithm, that uses nested loops.

The question of nested loops and recursion might as well be addressed with a familiar algorithm.

Page 110: Chapter 32 Slides

// Java3215.java Recursive Bubble-Sort Algorithm// This program uses an incorrect base-case and does not execute properly.import java.util.Random;public class Java3215{

public static void main(String args[]){

int intList[] = new int[40];enterList(intList);displayList(intList);sortList(intList,1,0);displayList(intList);

}public static void sortList(int list[], int p, int q){

int n = list.length;if (p < n-1) {

if (q < n-p) {if (list[q] > list[q+1]){

int temp = list[q]; list[q] = list[q+1]; list[q+1] = temp;} sortList(list,p,q+1);

}sortList(list,p+1,0);

}}

Page 111: Chapter 32 Slides

// Java3216.java Recursive Bubble-Sort Algorithm// This program uses a correct base-case and does execute properly. The key difference is // the else statement and initializing the q parameter to 0 for each comparison pass.import java.util.Random;public class Java3216{

public static void main(String args[]){

int intList[] = new int[40];enterList(intList);displayList(intList);sortList(intList,1,0);displayList(intList);

}public static void sortList(int list[], int p, int q){

int n = list.length;if (p < n-1) {

if (q < n-p) {if (list[q] > list[q+1]) {

int temp = list[q]; list[q] = list[q+1]; list[q+1] = temp;} sortList(list,p,q+1);

}else

sortList(list,p+1,0);}

}

Page 112: Chapter 32 Slides
Page 113: Chapter 32 Slides

The Merge Sort Case StudyIt is not always the case that programmers must select between a recursive solution or an iterative solution.

There are times when it makes the most sense to combine both methods.

Keep in mind that recursion is slower, and recursion uses more memory than iteration.

This means it is wise to use iteration whenever it is possible to do so without creating unnecessary complexity.

One such example of combining iteration with recursion is the Merge Sort.

Page 114: Chapter 32 Slides

The Merge Sort Case Study

23 34 35 39 50 75 90 9272

17 18 29 46 61 8582

23 34 35 39 50 75 90 9272

17 18 29 46 61 8582

23 34 35 39 50 75 90 927217 18 29 46 61 8582

Page 115: Chapter 32 Slides

// Java3217.java Merge Case Study, Step 1// Stub program for the MergeSort case studypublic class Java3217{

public static void main(String args[]){

System.out.println("\nMerge Sort Case Study, Step 1\n");int intList1[], intList2[], intList3[];intList1 = new int[20];intList2 = new int[20];intList3 = new int[20];initialize(intList1, intList2);merge(intList1, intList2, intList3);display(intList1, intList2, intList3);System.out.println();

}public static void initialize(int list1[], int list2[]){

System.out.println("\nCalling Method initialize\n");}public static void merge(int list1[], int list2[], int list3[]){

System.out.println("\nCalling Method merge\n");}public static void display(int list1[], int list2[], int list3[]){

System.out.println("\nCalling Method display\n");}

}

Page 116: Chapter 32 Slides

// Java3218.java Merge Case Study, Step 2

// This program merges two sorted integer arrays into

// a third array.

public class Java3218

{

public static void main(String args[])

{

System.out.println(

"\nMerge Sort Case Study, Step 2\n");

int intList1[], intList2[], intList3[];

intList1 = new int[20];

intList2 = new int[20];

intList3 = new int[20];

initialize(intList1, intList2);

merge(intList1, intList2, intList3);

display(intList1, intList2, intList3);

}

public static void initialize(int list1[], int list2[])

{

int k = 10;

for (int p = 0; p < 10; p++)

{

list1[p] = k; k++;

list2[p] = k; k++;

}

}

public static void merge(int list1[], int list2[], int list3[]){

int p = 0; int q = 0; int k = 0;while (p < 10 && q < 10) {

if (list1[p] <= list2[q]) {list3[k] = list1[p]; p++;

}else {

list3[k] = list2[q]; q++;}k++;

} while (p < 10) {

list3[k] = list1[p]; p++; k++; }

while (q < 10) {list3[k] = list2[q]; q++; k++;

}}

public static void display(int list1[], int list2[], int list3[]){

for (int p = 0; p < 10; p++)System.out.print(list1[p] + " ");

System.out.println("\n\n");for (int q = 0; q < 10; q++)

System.out.print(list2[q] + " ");System.out.println("\n\n");for (int r = 0; r < 20; r++)

System.out.print(list3[r] + " ");System.out.println();

}

Page 117: Chapter 32 Slides

// Java3219.java Merge Case Study, Step 3// This program demonstrates how to merge 2 sorted// halves of one array into one totally sorted array.

public class Java3219{

public static void main(String args[]){

System.out.println("\nMerge Sort Case Study, Step 3\n");

int intList[] = new int[20];initialize(intList);display(intList);merge(intList);display(intList);System.out.println();

}

public static void initialize(int list[]){

int mid = list.length / 2;int k = 1;for (int p = 0; p < mid; p++){

list[p] = k; k++;list[p+mid] = k; k++;

}}

public static void merge(int list[])

{

int n = list.length; int mid = n/2;

int p = 0; int q = mid; int k = 0;

int temp[] = new int[100];

while (p < mid && q < n) {

if (list[p] <= list[q]) {

temp[k] = list[p]; p++;

}

else {

temp[k] = list[q]; q++;

}

k++;

}

while (p < mid) {

temp[k] = list[p]; p++; k++;

}

while (q < n) {

temp[k] = list[q]; q++; k++;

}

for (int h = 0; h < n; h++)

list[h] = temp[h];

}

Page 118: Chapter 32 Slides

// Java3220.java Merge Case Study, Step 4// This program demonstrates how to merge 2 sorted// sections of one array into one larger sorted section.public class Java3220{

public static void main(String args[]){

System.out.println("\nMerge Sort Case Study, Step 4\n");

int intList[] = new int[20];int n = intList.length;initialize(intList);display(intList);int mid = n/2; int first = mid - 4;int last = mid + 3;merge(intList, first, mid, last);display(intList);System.out.println();

}public static void initialize(int list[]){

int mid = list.length / 2; int k = 1;for (int p = 0; p < mid; p++) {

list[p] = k; k++;list[p+mid] = k; k++;

}}

public static void merge(int list[], int first, int mid, int last)

{

int n = list.length; mid = n/2;

int p = first; int q = mid; int k = first;

int temp[] = new int[100];

while (p < mid && q <= last) {

if (list[p] <= list[q]) {

temp[k] = list[p]; p++;

}

else {

temp[k] = list[q]; q++;

}

k++;

}

while (p < mid) {

temp[k] = list[p]; p++; k++;

}

while (q < last) {

temp[k] = list[q]; q++; k++;

}

for (int h = first; h <= last; h++)

list[h] = temp[h];

}

Page 119: Chapter 32 Slides

Understanding the Merge Sort

456 143 678 342 809 751 500179

Divide the List in Half

456 143 678 342 809 751 500179

Page 120: Chapter 32 Slides

Divide the List in Half Again

And Again…

456 143 678 342 809 751 500179

456 143 678 342 809 751 500179

Page 121: Chapter 32 Slides

Important Merge Sort FactsThe merge sort works either by merging 2 sorted lists into a 3rd sorted list

or by merging 2 sorted sections of one list.

In either case, what is being merged must be sorted.

The merge sort will recursively divide a list in half again and again until every sub-list has a size of 1.

This is the base case for the merge sort.

It is also what makes it work since a list of only 1 element must be sorted.

Page 122: Chapter 32 Slides

All Lists Have a Size of 1

First Merge

143 456 342 678 809 500 751179

456 143 678 342 809 751 500179

Page 123: Chapter 32 Slides

Second Merge

456143 678342 809751500179

Final Merge - List is Sorted

456143 678342 809751500179

Page 124: Chapter 32 Slides

Merge Sort AlgorithmAs long as the lists are greater than one, continue the following four steps:

[1] Find the midpoint of the current list

[2] Make a recursive call to sort the first half of the list

[3] Make a recursive call to sort the second half of the list

[4] Merge the two sorted halves of the list

Page 125: Chapter 32 Slides

// Java3221.java Merge Case Study, Step 5// This program demonstrates the complete // MergeSort program Note that it is a// combination of an "iterative" <merge>// method and a "recursive" <mergeSort> method.import java.util.Random;public class Java3221{

public static void main(String args[]){

System.out.println("\nMerge Sort Case Study, Step 5\n");

int intList[] = new int[160];initialize(intList);display(intList);mergeSort(intList, 0, intList.length-1);display(intList);System.out.println();

}public static void mergeSort(int list[], int first, int last){

if (first < last) {int mid = (first + last) / 2;mergeSort(list,first,mid);mergeSort(list,mid+1,last);merge(list,first,mid,last);

}}

public static void merge(int list[], int first, int mid, int last)

{

int n = list.length; int temp[] = new int[2 * n];

int p = first; int q = mid+1; int k = first;

while (p <= mid && q <= last) {

if (list[p] <= list[q]) {

temp[k] = list[p]; p++;

}

else {

temp[k] = list[q]; q++;

}

k++;

}

while (p <= mid) {

temp[k] = list[p]; p++; k++;

}

while (q <= last) {

temp[k] = list[q]; q++; k++;

}

for (int h = first; h <= last; h++)

list[h] = temp[h];

}

Page 126: Chapter 32 Slides
Page 127: Chapter 32 Slides
Page 128: Chapter 32 Slides

// Java3222.java

// This program demonstrates mutual recursion.

import java.util.Random;

public class Java3222

{

public static void main(String args[])

{

System.out.println("\nJava3222.java\n");

int intList1[] = new int[20];

int intList2[] = new int[20];

initialize(intList1,intList2);

leftColumn(0,intList1,intList2);

System.out.println();

}

public static void initialize(int list1[], int list2[])

{

Random rndInt = new Random(12345);

for (int k = 0; k < list1.length; k++)

{

list1[k] = rndInt.nextInt(900) + 100;

list2[k] = rndInt.nextInt(900) + 100;

}

}

public static void leftColumn(int k,

int list1[], int list2[])

{

System.out.print(list1[k] + " ");

rightColumn(k,list1,list2);

}

public static void rightColumn(int k,

int list1[], int list2[])

{

System.out.println(list2[k] + " ");

if (k < list1.length-1)

leftColumn(k+1,list1,list2);

}

}

Page 129: Chapter 32 Slides

// Java3223.java

// This program demonstrates mutual and

// self recursion.

import java.util.Random;

public class Java3223

{

public static void main(String args[])

{

int intList1[] = new int[20];

int intList2[] = new int[18];

initialize(intList1,intList2);

leftColumn(0,intList1,intList2);

System.out.println();

}

public static void initialize(int list1[],

int list2[])

{

Random rndInt = new Random(12345);

for (int p = 0; p < list1.length; p++)

list1[p] = rndInt.nextInt(900) + 100;

for (int q = 0; q < list2.length; q++)

list2[q] = rndInt.nextInt(90) + 10;

}

public static void leftColumn(int k, int list1[], int list2[]){

if (k < list1.length)System.out.print(list1[k] + " ");

if (k < list2.length)rightColumn(k,list1,list2);

elseif (k < list1.length) {

System.out.println(); leftColumn(k+1,list1,list2);

}}public static void rightColumn(int k, int list1[ ], int list2[ ]){

if (k < list2.length)System.out.println(list2[k] + " ");

if (k < list1.length)leftColumn(k+1,list1,list2);

else if (k < list2.length) {

System.out.print(" "); rightColumn(k+1,list1,list2);

}}}