Download presentation
Presentation is loading. Please wait.
Published byNelson Lane Modified over 9 years ago
1
Recursion1
2
2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to solve one or more identical but smaller version(s) of the same problem. Examples: Binary Search Finding n th Fibonacci number Finding Factorials Finding exponents TOH Finding your way out of maze 8-queens problem Graph traversal problems … i.e., To solve problem of “size n”, first solve the same problem of “size n-1 or less”. How are each of these recursive problems?
3
Recursion3 First understanding a method and method call: For a method, the method call defines the problem size: … method(int k){ //method implementation //solves problem of size k } Solve a problem of “size n”- method(n) Solve a problem of “size n-1”- method(n-1) Solve a problem of “size n/2”- method(n/2) Solve a problem of “size 1”- method(1) Implicit sizes Solve a problem over an array of n elements - method(int[] array, int left, int right);
4
Recursion4 x n/2 * x n/2, if n is even x n/2 * x n/2 * x, if n is odd Recursive problems and methods: Problem:Find the exponent x n First First solve x n-1 To find: x n x n = x n-1 * x 1 … x 2 = x 1 * x 1 x 1 = x 0 * x 1 x 0 = 1 Recursive solution 1:Recursive solution 2: x n = Recursive problems are those problems where in order to solve the original problem you have to solve one or more identical but smaller version(s) of the problem until you reach the trivial or base case. To find: x n First First solve x n/2 … x 2 = x 1 * x 1 x 1 = x 0 * x 0 * x 1 x 0 = 1 Trivial or base case
5
Recursion5 Recursive problems and methods: Problem: Corresponding method signature: Find the exponent x n /** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n */ public static double power(double x, int n) Usage: Solve 5^3- power(5,3); Solve 0.031^9- power(0.031,9); Solve 10472834^0- power( 10472834,0); Solve x^n- power(x,n) Solve x^(n-1)- power(x,n-1)
6
Recursion6 Recursive problems and methods: Connecting the problem and the code x n = x n-1 * x 1 The problemThe method signature /** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n */ public static double power(double x, int n) Solve x n = power(x,n) = power(x,n-1) * x +
7
Recursion7 Recursive problems and methods: Problem: Corresponding method: Find the exponent x n Recursive solution: /** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n */ public static double power(double x, int n) Solve x^(n-1) Solve x^n x n = x n-1 * x 1 … x 1 = x 0 * x 1 x 2 = x 1 * x 1 x 0 = 1 { if (n == 0)return 1; Base case always first! Recursion next double ans = power(x,n-1) * x; return ans; }
8
Recursion8 Recursive problems and methods: Trace the following call: … System.out.println(power(5,4));...
9
Recursion9 Recursive problems and methods: Problem: Corresponding method: Find the exponent x n Recursive solution: /** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n */ public static double power(double x, int n) double xn; double xno2 = power(x,n/2); if (n%2 == 0)xn = xno2 * xno2; else xn = xno2 * xno2 *x; return xn; } Solve x n/2 Solve x^n { if (n == 0)return 1; x n/2 * x n/2, if n is even x n/2 * x n/2 * x, if n is odd x n = … x 2 = x 1 * x 1 x 1 = x 0 * x 0 * x 1 x 0 = 1
10
Recursion10 Recursion - Can you do this? Find x! as follows: 0! = 1 x! = x*(x-1)! /** * purpose of this method is to calculate n! * @param n - the value whose factorial we have to find * @return n! */ public static double factorial(int n)
11
Recursion11 Recursion - another example: Problem: f(n) = 1, when n is 0 or 1 f(n) = f(n-1) + f(n-2) when n > 1 Base case Recursive case /** * Finds the nth Fibonacci number * @param n - the index of the Fibonacci number to find, n >= 0 * @return nth Fibonacci number */ public static int fibonacci(int n){ if ((n==0) || (n==1)) return 1; //apparently, n is not 0 or 1 return fibonacci(n-1) + fibonacci(n-2); } Trace the following: System.out.println(fibonacci(4));
12
Recursion12 Recursion: Inherent cost of recursion: A lot of system overhead associated with method calls Advantages of recursion: Provides a clear readable intuitive solution to the problem.
13
Recursion13 How to problem solve recursively Given a problem of size n ask the following question: “ASSUMING I knew the solution to a smaller but identical sub problem, can I use that answer to solve my current problem?” If “yes”, how do you proceed? 1. Imagine m() to be a method that will solve all such smaller problems. 2. Imagine calling m() and incorporate the solution from m() to solve current problem. [ Think carefully about the signature of m(). ] 3. What size is the smallest sub problems? ( Note: smallest sub problem cannot be broken apart because if it could that would imply a still smaller problem! ) 4. All such small sub problems found in 3 are your base cases. 5. Replace all m() ‘s with a call to your self. 6. Put all the pieces together.
14
Recursion14 How to problem solve recursively Problem: Write a method to find x n Can this problem be solved recursively? “ASSUMING I knew the solution … 1. Imagine a method m() that will solve this problem, and call it m(x,n-1) -> returns an int, x n-1 2. Imagine calling m() and incorporating that solution to solve … int x_to_n = x * m(x, n-1) 3. What size is the smallest sub problems? n = 0, x 0 = 1 4. All such small sub problems found in 3 are your base cases. if (n == 0) return 1; 5. Replace all m() ‘s with a call to your self. int x_to_n = x * power(x,n-1);
15
Recursion15 How to problem solve recursively 6. Put all the pieces together. public static int power(int x, int n){ if (n == 0) return 1; //apparently, n is not zero int x_to_n = x * power(x,n-1); return x_to_n; }
16
Recursion16 The (classic) Towers of Hanoi problem Objective: To move n rings from any peg start peg ( s ) to any destination peg ( d ), without 1. moving more than one ring at a time, and 2. without placing a larger ring on top of a smaller ring. Analysis/algorithm: ? peg 1peg 2peg 3 Is it recursive? What would method m() look like? Can we phrase the solution in terms of m() ? s = 1, d = 3
17
Recursion17 Towers of Hanoi problem /** * The purpose of this method is to solve the towers of Hanoi * problem for n rings being moved amongst 3 pegs, numbered 1,2 * and 3. * @param n - the number of rings to move * @param o - the origination peg (where the rings currently are) * @param d - where the rings should be moved too */ public static void toh(int n, int o, int d){ //check for base if (n == 1) System.out.println(“move a ring from “+o+” to “+d); else{ toh(n-1,o, 6-o-d); System.out.println(“move a ring from “+o+” to “+d); toh(n-1, 6-o-d, d); }
18
Recursion18 Towers of Hanoi problem TOH(3,1,3) TOH(2,1,2) TOH(1,1,3)TOH(1,3,2) TOH(2,2,3) TOH(1,2,1)TOH(1,1,3) Trace: toh(3,1,3) What is the performance of toh() ?
19
Recursion19 Recursion and arrays - print an array out, backwards Problem: print an array backwards. Can this problem be solved recursively? 1. Imagine a method m() that will solve this problem. [ Think carefully about the signature of such a method. ] 2. Imagine calling m() and incorporating that solution to solve … 3. What size is the smallest sub problems? 4. All such small sub problems found in 3 are your base cases. 5. Replace all m() ‘s with a call to your self. [ What happens if the signatures don’t match? ] 6. Put all the pieces together. Performance?
20
Recursion20 Searching an array Problem: Search and array, A, of integers for a value B. If found return location index; otherwise return –1. Performance?
21
Recursion21 Recursion - Divide and Conquer - Binary search /** * This method searches an array of sorted Comparable objects * @param a - the array of sorted Comparable objects * @val - the value searched for * @l - the left starting index * @r - the right starting index * @return array index of value if found; -1 otherwise. */ public static int binarySearch(int[] a, int val, int l, int r){ if (l > r)return -1; //not found int mid = (l+r)/2; if (val == a[mid])return mid; //found if (val < a[mid])return binarySearch(a,val,l,mid-1); elsereturn binarySearch(a,val,mid+1,r); } Performance?
22
Recursion22 Sorting an array Problem: Sort an integer array, A. What recursive strategies can we use, if any? Can you come up with any?
23
Recursion23 Recursion - Divide and Conquer - Merge Sort /** This method will sort an array using merge sort*/ public static int[] sort(int a[]){ return mergeSort(a, l, r); } /** This method will sort an array of Comparable objects * using Merge sort * @param array - the array to sort * @param l - the left index * @param r - the right index */ public static void mergeSort(int[] array, int l, int r){ if (l < r){ int mid = (l+r)/2;//divide in half mergeSort(array, l, mid);//sort each half mergeSort(array, mid+1, r); merge(array, l,mid,r);//merge sorted halves } public static void merge(int[] array, int l, int mid, int r){ 1. create a temp array to hold the merging halves 2. merge the two halves 3. Make sure all elements of the two halves are in the temp array 4. Copy elements from the temp array back to array. } Performance?
24
Recursion24 Recursion - Divide and Conquer - Merge Sort public static void merge(int[] array, int l, int mid, int r){ //create an array int[] temp = new int[r+1]; //merge int li=l, ri = mid+1, ti = l-1; while ((li <= mid) && (ri <= r)){ ti++; if (array[li] < array[ri]){ temp[ti] = array[li]; li++; } else{ temp[ti] = array[ri]; ri++; } // Make sure all elements of the two halves are in the temp array for(int i=li; i<=mid; i++, ti++) temp[ti] = array[i]; for(int i=ri; i<=r; i++, ti++) temp[ti] = array[i]; //Copy elements from the temp array back to array. for(int i=l; i<=r; i++) array[i] = temp[i]; }
25
Recursion25 Recursion - Divide and Conquer - Quick Sort Problem: Sort an integer array, A. public static int[] sort(int[] a) Can this problem be solved recursively? Imagine 1: Move elements in array into the left and right of the array such that all the elements on the left are less than some pivot value and all the elements to the right are greater. Imagine that you know this break even index. Imagine 2: Imagine that m() is a method that will sort an array’s elements between l and r: int[] m(int[] a, int l, int r) 2. Imagine calling m() and incorporating that solution to solve … int pivIndex = partition(a, l,r); m(a,l,pivIndex-1); m(a,pivIndex+1, r); 3. Base case(s) if (l < r) {
26
Recursion26 Recursion - Divide and Conquer - Quick Sort /** This method will sort an array using quick sort*/ public static int[] sort(int a[]){ return quiskSort(a, l, r); } /** This method will sort an array of Comparable objects * using Quick sort * @param array - the array to sort * @param l - the left index * @param r - the right index */ private static void quickSort(int[] array, int l, int r){ if (l < r){ int pivot = partition(array,l,r); quickSort(array, l, pivot-1); //sort each half quickSort(array, pivot+1, r); } private static void partition(int[] array, int l,int r){ 0. Pivot value is array[l] 1. Scan from left to right and right to left moving items larger than pivot to the right and those smaller than pivot to the left 2. Move pivot to its sorted position 3. return pivot index } Performance?
27
Recursion27 Recursion - Divide and Conquer - Quick Sort public static void partition(int[] array, int l,int r){ //Pivot value is array[l] int pivotVal = array[l]; //Scan from left to right and right to left moving items larger //than pivot to the right and those smaller than pivot to the left int li = l, ri = r; while (li < ri){ while ((pivotVal > array[li]) && (li<ri)) li++; while (pivotVal < array[ri]) ri--; if (li<ri){ int temp = array[li]; array[li] = array[ri]; array[ri] = temp; li++; ri--; } //Move pivot to its sorted position array[l] = array[ri]; array[ri] = pivotVal; //return pivot index return ri; }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.