37
Chapter 14 Recursion Lecture Slides to Accompany An Introduction to Computer Science Using Java (2nd Edition) by S.N. Kamin, D. Mickunas, , E. Reingold

Chapter 14 Recursion

  • Upload
    reidar

  • View
    30

  • Download
    2

Embed Size (px)

DESCRIPTION

Chapter 14 Recursion. Lecture Slides to Accompany An Introduction to Computer Science Using Java (2nd Edition) by S.N. Kamin, D. Mickunas, , E. Reingold. Chapter Preview. In this chapter we will: introduce recursion as a programming technique - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter 14 Recursion

Chapter 14

Recursion

Lecture Slides to Accompany

An Introduction to Computer Science Using Java (2nd Edition)

by

S.N. Kamin, D. Mickunas, , E. Reingold

Page 2: Chapter 14 Recursion

Chapter Preview

In this chapter we will:• introduce recursion as a programming technique • show how recursion can be used to simplify the design

of complex algorithms • present several well known recursive algorithms

(e.g. quicksort, merge sort, Guaussian elmination)• introduce the linked list data structure and recursive

implementations for several of its methods• present programs for drawing two types of fractal

curves

Page 3: Chapter 14 Recursion

Recursion

• Basic problem solving technique is to divide a problem into smaller subproblems

• These subproblems may also be divided into smaller subproblems

• When the subproblems are small enough to solve directly the process stops

• A recursive algorithm is a problem solution that has been expressed in terms of two or more easier to solve subproblems

Page 4: Chapter 14 Recursion

Counting Digits

• Recursive definitiondigits(n) = 1 if (–9 <= n <= 9)

1 + digits(n/10) otherwise

• Exampledigits(321) =

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

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

1 + [1 + (1)] =

3

Page 5: Chapter 14 Recursion

Counting Digits in Java

int numberofDigits(int n) {

if ((-10 < n) && (n < 10))

return 1

else

return 1 + numberofDigits(n/10);

}

Page 6: Chapter 14 Recursion

Recursion

• If you want to compute f(x) but can’t compute it directly

• Assume you can compute f(y) for any value of y smaller than x

• Use f(y) to compute f(x)• For this to work, there has to be at least one

value of x for which f(x) can be computed directly (e.g. these are called base cases)

Page 7: Chapter 14 Recursion

Evaluating Exponents Recurisivley

static int power(int k, int n) {

// raise k to the power n

if (n == 0)

return 1;

else

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

}

Page 8: Chapter 14 Recursion

Divide and Conquer

• Using this method each recursive subproblem is about one-half the size of the original problem

• If we could define power so that each subproblem was based on computing kn/2 instead of kn – 1 we could use the divide and conquer principle

• Recursive divide and conquer algorithms are often more efficient than iterative algorithms

Page 9: Chapter 14 Recursion

Evaluating Exponents Using Divide and Conquer

static int power(int k, int n) { // raise k to the power n 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 10: Chapter 14 Recursion

Selection Sort

private static void selectionSort

(double[] A, int lo, int hi) {

// A[0]..A[lo-1] contain smallest

// values in A, in ascending order

if (lo < hi) {

swap(A, lo, findMiniumum(A, lo, hi);

selectionSort(A, lo + 1, hi);

}

}

Page 11: Chapter 14 Recursion

Find Minimumprivate static int findMinimum

(double[] A, int lo, int hi) {

if (lo == hi)

return lo;

else {

int locationOfMin = findMinimum(A, lo + 1, hi);

if (A[lo] < A[locationOfMin])

return lo;

else

return locationOfMin;

}

}

Page 12: Chapter 14 Recursion

Selection Sort Helper Function

• Client programs should not need to know anything about how selectionSort was implemented

• A single argument helper function can be used to help clients make use of the new version

• Examplepublic static void selectionSort(double[] A) { selectionSort(A, 0, A.length – 1);}

Page 13: Chapter 14 Recursion

Insertion Sort

private static void insertionSort

(double[] A, int hi) {

// Sort A[0] .. A[hi]

if (hi > 0) {

insertionSort(A, hi – 1);

insertInOrder(A, hi, A[hi));

}

}

Page 14: Chapter 14 Recursion

Insert in Order

private static void insertInOrder (double[] A, int hi, double x) { // Insert x into A[0]..A[hi-1], // filling in A[hi} in the process. // A[0]..A[hi – 1] are sorted. if ((hi == 0) || (A[hi – 1] <= x)) A[hi] = x; else A[hi] = A[hi – 1]; insertInOrder(A, hi – 1, x); }}

Page 15: Chapter 14 Recursion

Insertion Sort Helper Function

• Again we should provide potential clients with a single argument helper functon

public static void InsertionSort(double[] A) {

InsertionSort(A, A.length – 1);

}

Page 16: Chapter 14 Recursion

Quicksort Overview

• Choose the middle element among A[lo]..A[hi]• Move other elements so that

– A[lo]..A[m – 1] are less than A[m]– A[m + 1]..A[hi] are greater than A[m]

• Return m to the caller

Page 17: Chapter 14 Recursion

Quicksort

static void quickSort

(double[] A, int lo, int hi) {

int m;

if (hi > lo + 1) { // 3 or more subarray values

m = partition(A, lo, hi);

quickSort(A, lo, m – 1);

quickSort(A, m + 1, hi);

}

else // less than 3 subarray values

if ((hi == lo + 1) && (A[lo] > A[hi])

swap(A, lo, hi);

}

Page 18: Chapter 14 Recursion

Partition

static int partition (double[] A, int lo, int hi) {

// choose middle element from A[lo}..A[hi]

// move elements so A[lo]..A[m-1] are all < A[m]

// move elements so A[m+1]..A[hi] are all > A[m]

swap(A, lo, medianLocationA, lo+1, hi, (lo+hi)/2));

int m = partition(A, lo+1, hi, A[lo]);

swap(A, lo, m);

return m;

}

Page 19: Chapter 14 Recursion

Partition Helper

static int partition (double[] A, int lo, int hi, double pivot) { if (hi == lo) if (A[lo] < pivot) return lo; else return lo – 1; else if (A[lo] <= pivot) // A[lo] in correct half return partition(A, lo + 1, hi, pivot); else { // A[lo] in wrong half swap(A, lo, hi); return parition(A, lo, hi – 1, pivot); } }

Page 20: Chapter 14 Recursion

Median Locationstatic int medianLocation (double[] A, int i, int j, int k) { if (A[i] <= A[j]) if (A[j] < A[k]) return j;0 else if (A[i] <= A[k]) return k; else return i; else // A[j] < A[i] if (A[i] <= A[k]) return i; else if (A9j] <= A[k]) return k; else return j;}

Page 21: Chapter 14 Recursion

Linear Systems

a11x1 + a12x2 + … + a1nxn = b1

a11x1 + a12x2 + … + a1nxn = b1

… … … …

a11x1 + a12x2 + … + a1nxn = b1

Page 22: Chapter 14 Recursion

Solving Linear Systems

solve (System E of n equations in n unkonwns) { if (n == 1) // system is ax = b return (b/a); else { eliminate last equation yielding system E’;

solve(E’), yielding x1, … ,xn-1;

xn = (bn – an,1x1 - … - a1,n-2xn-1)/ an,n

return (x1, … , xn-1, xn);

}}

Page 23: Chapter 14 Recursion

Integer List Class

class IntList { private int value; private IntList tail; public IntList(int v, IntList next) { value = v; tail = next; } public int getValue () { return value; } public intList getTail (){ return Tail; }

Page 24: Chapter 14 Recursion

Constructing a Linked List

• One approach would be:IntList list = new IntList(-14, null);list = new IntList(616, list);list = new IntList(10945, list);list = new IntList(17, list);

• Alternatively we could have written:IntList list = new IntList(17, new IntList(616, new IntList(10945, new IntList(17, null))));

Page 25: Chapter 14 Recursion

Constructing a Linked List from Input

Intlist readReverseList () { int inputval; IntList front = null; Inputbox in = new IntputBox(); while (true){ inputval = in.readInt(); if (in.eoi)) break; front = new IntList(inputval, front); } return front;}

Page 26: Chapter 14 Recursion

Printing Linked List

void print (IntList list) {

Output out new OutputBox();

while (list != null) {

out.print(list.getValue() + “ “);

list = list.getTail();

}

out.println();

}

Page 27: Chapter 14 Recursion

Computing List Length

• This method would be added to IntListpublic int length() {

if (tail == null)

return 1;

else

return 1 + tail.length();

}

Page 28: Chapter 14 Recursion

Converting List to String

• This method would be added to IntList

public String toString() {

String myValue = Integer.toString(value);

if (tail == null)

return myValue;

else

return myValue + “, “ + tail.toString();

}

Page 29: Chapter 14 Recursion

Retrieving nth List Element

• This method would be added to IntList

public IntList nth(int n) {

if (n = 0)

return this;

else if (tail == null)

return null;

else

return tail.nth(n – 1);

}

Page 30: Chapter 14 Recursion

Adding Element to End of List

• This method would be added to IntList

public void addToEndM(int n) {

if (tail != null)

// in the middle of the list

tail.addToEndM(n);

else

// at last cell

tail = new IntList(n, null);

}

Page 31: Chapter 14 Recursion
Page 32: Chapter 14 Recursion

Adding Element to List in Order

• This method would be added to IntListpublic IntList addInorderM(int n) { if (n < value) return new IntList(n, this); else if (n == value) return this; if (tail != null){ tail = new IntList(n, null); return this; } else{ tail = tail.addInorderM(n); return this; }}

Page 33: Chapter 14 Recursion
Page 34: Chapter 14 Recursion

MergeSort

public static IntList mergeSort (IntList L) {// Sort L by recursively splitting and merging if ((L == null) || (L.getTail() == null); // zero or one item return L; else { // two or more items // Split the list into two parts IntListPair p = L.split(); // Sort and merge the two parts return mergeSort(p.x).merge(mergeSort(p.y)); }}

Page 35: Chapter 14 Recursion

IntListPair

class IntListPair {

public IntList x, y;

public IntListPair (IntList x, IntList y) {

this.x = x;

this.y = y;

}

}

Page 36: Chapter 14 Recursion

Splitting the List

• This method would be added to IntListPair

public IntList split() {

if (tail != null)

return = new IntListPair(this, null);

else{

IntListPair p = tail.split();

return new

IntListPair(new IntList(value,p.y),p.y);

}

}

Page 37: Chapter 14 Recursion

Merging the Lista

• This method would be added to IntListIntList merge(IntList L) {

if (L = null)

return this;

if (value < L.value)

if (tail == null)

return new IntList(value, L);

else

return new IntList(value, tail.merge(L));

return new

return new IntList(L.value,merge(L.tail));

}

}