71
Chapter 16 Recursion

Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Embed Size (px)

Citation preview

Page 1: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Chapter 16Recursion

Page 2: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

This chapter discusses

Recursion. Comparison of recursion and iteration.

Recursive solutions using class structure, rather than algorithm design to control recursion.

Page 3: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Iteration and recursion

In iteration, the algorithm specifies a step in the solution process that is to be repeated or iterated.

Recursion involves providing a solution to a trivial, base case of the problem, and then designing a solution to the general case by showing how to “reduce” the general case to one that is a step closer to the base case; the algorithm invokes itself to solve the “slightly reduced” case.

Page 4: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursion

Page 5: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive selection sort

Base Case: sort a list that is empty or contains only a single element.

General Case: sort a list containing n elements, where n > 1. Find the smallest element and put it first. Sort the remaining n-1elements. (This is

done by invoking the method itself.) These “self-calls” continue until the base

case is reached.

Page 6: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort

private void sort (List list, int

first, int last, Order compare){

int small // index of smallest

if (last > first) {

small = smallestOf(list, first,

last, compare);

interchange(list, first, small);

sort(list, first+1,last,compare);

}

}

Page 7: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Verification of correctness Use induction. The base cases of the induction

match the base cases of the algorithm.

The general case of the induction handles the general case of the algorithm.

Page 8: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort

Page 9: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 10: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

We now have two sets of local variables – one for each invocation of the method sort.

This is like invoking two different methods; the fact that they happen to be invocations of the same method is irrelevant.

Page 11: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 12: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 13: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 14: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 15: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Selection Sort (cont.)

Page 16: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Putting this procedure into a Sorter Provide a public method that calls the recursive

method with the appropriate arguments.

public class RecursiveSelectionSorter implements Sorter {

public void sort (List list, Order compare) {

sort(list,0,list.size()-1,compare);

}

private void sort (List list, int first, int last, Order compare) {…}

private int smallestOf (List list, int first, int last, Order compare) {…}

private void interchange (list list, int i, int j) {…}

}//end of class RecursiveSelectionSorter

Page 17: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Putting this procedure into a Sorter (cont.) The method name sort is overloaded. One sort defines the public interface. The other sort is a private "auxiliary"

method that does the work.

Page 18: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Towers of Hanoi

Move the stack of disks from the starting peg to one of the other pegs, moving only one disk at a time, and without placing a larger disk on top of a smaller disk.

Page 19: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Towers of Hanoi (cont.)

We model a move as a class instance. A move is characterized by the peg a disk is

moved from and the peg the disk is moved to.

Page 20: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi Base Case: Only one disk to move. General Case: Move a stack of n

disks, where n > 1. Moving n-1 disks is a step closer to

the base case. We can ignore the largest disk

when considering the n-1 smaller disks.

Page 21: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi (cont.) Move n-1 disks from the starting

peg to the “other” peg. Move a disk from the starting peg

to the destination peg. Move n-1 disks from the “other”

peg to the destination peg.

Page 22: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi (cont.) The client-server relationship is as

follows:

Page 23: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi (cont.)public class Move

A move in the Towers puzzle. Pegs are numbered 1,2,3.

public Move (int from, int to)

A move of a disk from “from” to “to”.

public int from ()

Peg the disk is moved from.

public int to ()

Peg the disk is moved to.

Page 24: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi (cont.)public void moveTower (int n, int

from, int to, SolverObserver o)Report to the specified observer the moves required to move a tower of the specified number of disks, from the specified starting peg to the specified destination peg.

require:

n >= 1

1 <= from <= 3 && 1 <= to <= 3

from != to

public void update (Move m)

Page 25: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Recursive algorithm for Towers of Hanoi (cont.)public void moveTower (int n, int from,

int to, SolverObserver o)if (n==1) { o.update(new Move(from,to));} else { int other = 6-from-to //peg that

//is not from or to //move n-1 disks to other peg moveTower(n-1,from, other,o); //move big disk to the target o.update(new Move(from,to)); //move n-1 disks to the target moveTower(n-1,other,to,o);}

}

Page 26: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Example: moveDisk(2,1,2,this)

Page 27: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather
Page 28: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather
Page 29: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort

Quick sort typically take on the order of n·log2n steps.

n n2 n·log2n10 100 33100 10,000 6641,000 1,000,000 9,96610,000 100,000,000 132,877100,000 10,000,000,000 1,660,9641,000,000 1,000,000,000,000 19,931,569

Quick sort starts by putting one element into position. Rather than positioning the largest or smallest element, quick sort puts an arbitrary element in proper position.

Page 30: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

1. Put an element in its proper sorted position, with smaller elements below an larger elements above.The positioned element is the “pivot” element.

2. Sort the sub-list of smaller elements below the positioned element.

3. Sort the sub-list of larger elements above the positioned element.

This is clearly recursive!

Page 31: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)public class QuickSorter extends Sorter {

/** * Sort specified List according to the * specified Order, using quick sort. */public void sort (List list, Order compare) sort(list, 0,list.size()-1,compare);}

/** * Sort list elements first to last */private void sort (List list, int first,

int last, Order Compare) { …}

}

Page 32: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Base case: an empty list or a list with a single element.

General Case: handled by the 3 steps mentioned earlier.

We separate step 1 out into its own method called partition.

partition changes the state of the list like a command, and returns a value like a query.

Page 33: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

public int partition (List list, int first, int last, Order compare)Partition list elements indexed first through last for quick sort; return the pivot position.require: 0 <= first < last < list.size()ensure: first <= result <= last for first <= i < result,

list.get(i) < list.get(result) for result <= i <= last,

list,get(i) >= list.get(result)

Page 34: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Suppose we chose to put 28 in its proper position.

The method returns value 6, the index of the “pivot” element.

Page 35: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

private void sort (List list, int

first, int last, Order compare) {

int position; //the pivot index

if(first < last) {

position = partition(list,first, last,compare);

sort(list,first,positions-1,compare);

sort(list,position+1,last,compare);

}

}

Page 36: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 37: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 38: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 39: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 40: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 41: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 42: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 43: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 44: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

Page 45: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

private int partition (List list, int first, int last, Order compare) {

int pi; //pivot index;

int i; //next item of 1 to examine

int mid; //middle index: (first+last)/2

Object item; // pivot item

mid = (first+last)/2;

item = list.get(mid);

//put pivot item at end of list

interchange(list,mid,last);

pi = first;

i = first; //haven’t examined anything//yes=t

Page 46: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)/* loop invariant: * for first <= j <pi * list.get(j) < item * for pi <= j < i * list.get(j) >= item */while (i != last) { //last is pivot index if (compare.lessThan(list.get(i),item)) {

interchange(list,pi,i)pi = pi+1;

} i = i+1;}interchange(list,pi,last); //put pivot item

//in placereturn pi;

}

Page 47: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Quick sort (cont.)

When the while loop is reached for the first time, the clauses of the invariant are vacuously true. Since first == pi == I, there is no value j such

that first <= j <= pi and there is no value j such that pi <= j < I.

We select the middle item because in the worst case, the algorithm could take order n2 time. If the list is ordered (or nearly ordered) and we chose the first or last elements in the list, the order is closer to n2 .

Page 48: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Inefficiency

It is often more difficult to design recursive algorithms that are as efficient as iterative algorithms.

Since we control the steps in an iterative process more directly than in a recursive process, inefficiencies often are more obvious in an iterative algorithm.

Page 49: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Fibonacci numbers

The sequence of integers beginning with 0 and 1, and in which each successive number is the sum of the previous two: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34…

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

}

Page 50: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Fibonacci numbers (cont.) Each level of recursion duplicates work

done at the previous level. Example: computing fib(6) requires

computing fib(5) and fib(4), but the computation of fib(5) also computes fib(4).

The time to compute fib(n) is roughly proportional to fib(n)!

An iterative approach solves the problem in computational time proportional to n.

Page 51: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Indirect recursion

A method can invoke itself indirectly.

m1 invokes m2 which invokes m3… which invokes mn which invokes m1.

Page 52: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Heads or Tails

public char head (String s)

The first character of the specified non-empty String.

public String tail (String s)

A String equal to the specified non-empty String with its first character removed.

head(“abc”) ‘a’tail(“abc”) “bc”

Page 53: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Balanced Parentheses

A function that removes the first balanced substring of parentheses.

“()” “”“()()()()” “()()()”“((()))” “”“(()()(()()))()(())” “()(())”

Page 54: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Balanced Parentheses (cont.)public String removeSet (String s)

A String equal to the specified String with the first balanced substring of parentheses removedrequire: s is a balanced string of parentheses

private String reduceClosed (String s)A String equal to the specified String with the first substring containing one more closed parenthesis than open parentheses removed.require:s is a string of parentheses that would be balanced if an open parenthesis were appended to the front; in particular, s contains one more closed parenthesis than open parentheses.

Page 55: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Balanced Parenthesis (cont.)public String removeSet (String s) {

if (s.equals(“”))

return “”;

else

// head(s) is ‘(‘

return reduceClosed(tail(s));

}

private String reduceClosed (String s) {

if ( head(s) == ‘)’ )

return tail(s);

else

//head(s) == ‘(‘;first remove a balanced set.

return reduceClosed(removeSet(s));

Page 56: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Object recursion

Structural recursion: using object structure in a recursive manner to derive problem solutions.

An object tasked with solving a problem gets assistance from a similar object which solves a simpler instance of the problem.

Page 57: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Object recursion (cont.)

Page 58: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer

A sequence of digits, in which one digit “turning over” from 9 to 0 causes its left neighbor to increment.

A “solution state” is a stable state of the counter, in which all the digits are set. In the first solution state, all digits are 0. A next solution state is reached when the

counter is incremented by 1. In the final solution state, all digits are 9.

Page 59: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer (cont.)

The solver class is Digit. The trivial solver class is NullDigit. Each Digit is responsible for a digit

of the solution.

Page 60: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer (cont.)

Each Digit has an associate, the Digit to its left. A Digit “extends” the solution provided by its

associate; a four-digit number, for example, is built by extending a three-digit number.

The right-most Digit in a 1-digit number has a NullDigit associate.

Page 61: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer (cont.)

Page 62: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer (cont.)

An inner class is a class defined inside another class.

We make AbstractDigit, Digit, and NullDigit inner classes of the DigitCounter.

Page 63: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

public class DigitCounter { /** * Create a new DigitCounter with the specified number of digits. * require: * digits >= 1 */

public DigitCounter (int digits) { int i; AbstractDigit d = new NullDigit(); for (i = 1; i <= digits; i = i+1) d = new Digit(d); lowDigit = d; } … private AbstractDigit lowDigit;//right most private abstract class AbstractDigit{…} private class NullDigit extends

AbstractDigit{…} private class Digit extends AbstractDigit{ private Digit(AbstractDigit associate) { this.associate = associate; … } … private AbstractDigit associate;//left

//neighbor

}}

Page 64: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Odometer (cont.)

command: solved: toString:-- false --

first true 00 next true 01 next true 02 … next true 99 next false --

Page 65: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

public class DigitCounter {…/** * Set to all zeros. */

public void first() { lowDigit.first();}/** * Increment this DigitCounter by 1 */

public void next () { lowDigit.next();}/** * First or next has been sucessfully performed */

public boolean solved() { return lowDigit.solved();}/** * Number contained in this DigitCounter * require: * this.solved() */

public String toString() { return lowDigit.toString();}

Page 66: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

private AbstractDigit lowDigit;//right-most

private abstract class AbstractDigit { public abstract boolean solved (); public abstract void first(); public abstract void next(); public abstract String toString();}

}

Page 67: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

private class Digit extends AbstractDigit { public Digit (AbstractDigit associate) {

this.associate = associate; this.digit = 0; this.solved = false;

}

public boolean solved () { return solved;

}

public void first () { associate.first(); if (associate.solved()) {

digit = 0;solved = true;

} elsesolved = false;

}

Page 68: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

public void next () { if (digit < 9) {

digit = digit + 1;solved = true;

} else {associate.next();if (associate.solved()) { digit = 0; solved = true;} else solved = false;

} }

public String toString () { return associate.toString() + digit;}public AbstractDigit associate () { return associate;}private AbstractDigit associate;//left

//neighborprivate boolean solved; //a valid numberprivate int digit; //my digit

}

Page 69: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

private class NullDigit extends AbstractDigit {

public boolean solved () { return solved;}public void first () { solved = true;}public void next () { solved = false;}public String toString () { return “”;}

private boolean solved;

} Class NullDigit permits all object entries

in the structure to be treated uniformly.

Page 70: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

We’ve covered

Recursive computation Algorithmic recursion Object recursion

Indirect recursion Structural recursion

Page 71: Chapter 16 Recursion. This chapter discusses n Recursion. n Comparison of recursion and iteration. n Recursive solutions using class structure, rather

Glossary