Presentation is loading. Please wait.

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

## Presentation on theme: "Chapter 14 Recursion Lecture Slides to Accompany An Introduction to Computer Science Using Java (2nd Edition) by S.N. Kamin, D. Mickunas,, E. Reingold."— Presentation transcript:

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 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

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

Counting Digits Recursive definition digits(n) = 1if (–9 <= n <= 9) 1 + digits(n/10)otherwise Example digits(321) = 1 + digits(321/10) = 1 +digits(32) = 1 + [1 + digits(32/10)] = 1 + [1 + digits(3)] = 1 + [1 + (1)] = 3

Counting Digits in Java int numberofDigits(int n) { if ((-10 < n) && (n < 10)) return 1 else return 1 + numberofDigits(n/10); }

Recursion If you want to compute f(x) but cant 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)

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); }

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 k n/2 instead of k n – 1 we could use the divide and conquer principle Recursive divide and conquer algorithms are often more efficient than iterative algorithms

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; }

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); }

Find Minimum private 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; }

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 Example public static void selectionSort(double[] A) { selectionSort(A, 0, A.length – 1); }

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)); }

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); }

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); }

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

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); }

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; }

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); }

Median Location static 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; }

Linear Systems a 11 x 1 + a 12 x 2 + … + a 1n x n = b 1 … … a 11 x 1 + a 12 x 2 + … + a 1n x n = b 1

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 x 1, …,x n-1 ; x n = (b n – a n,1 x 1 - … - a 1,n-2 x n-1 )/ a n,n return (x 1, …, x n-1, x n ); }

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; }

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))));

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; }

Printing Linked List void print (IntList list) { Output out new OutputBox(); while (list != null) { out.print(list.getValue() + ); list = list.getTail(); } out.println(); }

Computing List Length This method would be added to IntList public int length() { if (tail == null) return 1; else return 1 + tail.length(); }

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(); }

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); }

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); }

Adding Element to List in Order This method would be added to IntList public 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; }

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)); }

IntListPair class IntListPair { public IntList x, y; public IntListPair (IntList x, IntList y) { this.x = x; this.y = y; }

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); }

Merging the Lista This method would be added to IntList IntList 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)); }

Similar presentations

Ads by Google