1 / 23

Recursion

Recursion. Riley Chapter 14 Sections 14.1 – 14.5 (14.6 optional). 0! is 1 1! is 1 2! is 1 * 2 3! is 1 * 2 * 3. Factorial using repetition…. int factorial ( int n ) { int product, i ; product = 1 ; for ( i = n ; i > 1 ; i-- ) { product = product * i ; }

Télécharger la présentation

Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Recursion Riley Chapter 14 Sections 14.1 – 14.5 (14.6 optional)

  2. 0! is 1 1! is 1 2! is 1 * 2 3! is 1 * 2 * 3 . . . Factorial using repetition… int factorial ( int n ) { int product, i ; product = 1 ; for ( i = n ; i > 1 ; i-- ) { product = product * i ; } return (product) ; } method name Formal parameter local variables return type & value

  3. Review: Method Basics • Tracing recursive methods is easy if you remember method basics : • Formal parameters and variables declared in a method are local to it… • Allocated (created) on method entry • De-allocated (destroyed) on method return • Formal parameters initialized by copying value of actual parameter.

  4. 0! is 1 • 1! is 1 • n! is n * (n-1)!, for n>1 • E.g.: 3! =3 * 2! • = 3 * 2 * 1! • = 3 * 2 * 1 Factorial via Recursion /* 0! = 1! = 1; for n > 1, n! = n(n-1)! */ int factorial (int n) { int t; if (n <= 1) t = 1; else t = n * factorial(n - 1); return t; } Basis clause or “simple case” Recursive clause or general case -- “making progress”

  5. Factorial factorial(4) = 4 * factorial(3) = 4 * 3 * factorial(2) = 4 * 3 * 2 * factorial(1) = 4 * 3 * 2 * 1 = 24

  6. n t n t n t n t Factorial Trace The onlycommunication between methods is via parameters of the method call and return values. Every time a method is called (an “activation”), a stack frame is created for its local variables. Each activation has its own set!

  7. Iteration vs Recursion • Turns out any iterative algorithm can be reworked to use recursion instead. • Some algorithms are more naturally written with recursion than others • recursion is often less efficient • There are even programming languages where recursion is the only choice!

  8. Fibonacci (slightly different from the text) int jthFib(int j) { if (j <= 0) return 0; /* a "basis clause" or "base case" */ else if (j == 1) return 1; /* another base case */ else /*"recursive clause" or general case ("making progress"*/ return jthFib (j-1) + jthFib (j-2); } Recursive Fibonacci is elegant and compact, but not very efficient.

  9. Searching • Searching = looking for something • Like sorting, searching is a common and useful operation • Searching an array is very common • Goal: determine if a particular value is in the array • If the array is unsorted: • start at the beginning and look at each element to see if it matches

  10. There is a better way • "Binary search" works if the array is sorted 1. Look for the target in the middle. 2. If you don't find it, you can throw away half of the array, and repeat the process with the other half. • Turns out you only need about log2(size) comparisons

  11. Is it worth the trouble? • Suppose you had 1000 elements • Ordinary search would require 500 comparisons on average • Try a Binary search

  12. Binary Search • Try a Binary search • after 1st compare, throw away half, leaving 500 elements to be searched. • after 2nd compare, throw away half, leaving 250. Then 125, 63, 32, 16, 8, 4, 2, 1 are left. • After at most 10 steps, you're done! • What if you had 1,000,000 elements??

  13. Recursive Binary Search /*Precondition: the array is sorted */ /*Returns -1 if target not found; returns index of target if found */ int search (double[] a, double target, int low, int high) { int mid = (low+high)/2; if (target == a[mid]) return mid; /* found! */ if (low >= high) return -1; /* not found */ if (target < a[mid]) return search (a, target, low, mid-1); else return search (a, target, mid+1, high); }

  14. Kick-off • Each time search is called, it searches only a part of the array • The first time it's called, tell it to search everything public int testSearch( double target ) { final int snum = 8; double grades[ ] = {0.0, 0.7, 2.0, 2.8, 3.1, 3.3, 3.9, 4.0}; return( search (grades, target, 0, snum-1) ); }

  15. snum is 8 first call: search (grades, 3.9, 0, 7) i grades[i] 0 0.0 1 0.7 2 2.0 3 2.8 4 3.1 5 3.3 6 3.9 7 4.0

  16. Is Binary Search the Last Word? • For sorted arrays, yes. • Real-world data is often messier, unfortunately • In games: search for the best move is important • Chess: how many moves are possible at each stage of a game?? • Deep Blue has special hardware

  17. Quicksort To sort a set S: Choose a ‘pivot’ element x from S. Construct S1, the elements less than x Construct S2, the elements greater than x Sort the sets S1 and S2 Output the sorted S1, then x, then the sorted S2

  18. Quicksort Example 12, 15, 18, 8, 2, 19, 5, 13, 16, 9, 6, 1 8, 2, 5, 9, 6, 1, 12, 15, 18, 19, 13, 16 2, 5, 6, 1, 8, 9, 12, 13, 15, 18, 19, 16 1, 2, 5, 6, 8, 9, 12, 13, 15, 16, 18, 19

  19. Quicksort Implementation /* Sort subarray a[i],… a[j] */ void quickSort(int a[ ], int i, int j) { int k; if (i >= j) return; k = partition(a, i, j); quickSort(a, i, k-1); quickSort(a, k+1, j); }

  20. Partition(a, i, j) Restrict attention to the subarray a[i], ..., a[j] a[i] is the value of the pivot. Rearrange a[i], ..., a[j] so that elements less then the pivot are to the left of the pivot, and elements greater than the pivot are to the right of the pivot. Return the new position of the pivot.

  21. Partition Examples partition(a, 0, 11) 12 15 18 8 2 19 5 13 16 9 6 1 8 2 5 9 6 1 12 15 18 19 13 16 partition(a, 4, 8) 2 5 8 9 16 11 19 15 13 27 21 23 2 5 8 9 11 15 13 16 19 27 21 23 returns 6 returns 7

  22. A Partition Implementation /** partition a[i],... a[j] around pivot a[i] * @return new index of pivot */ int partition ( int a[ ], int i, int j ) { int pivot = a[i], left = i, right = j; while ( left < right ) { /* exchange next pair out of place */ while( left <= j && a[left] <= pivot ) left = left + 1; while ( a[right] > pivot && right >= I ) right = right -1; if ( left < right ) swap ( a, left, right ); } /* place pivot and return its index */ swap ( a, i, right ); return( right ); }

  23. Call Graph quick_sort(a, 0, 11) quick_sort(a, 0, 5) quick_sort(a, 7, 11) quick_sort(a, 0, 3) quick_sort(a, 5, 5) quick_sort(a, 7, 7) quick_sort(a, 9, 11) quick_sort(a, 0, 0) quick_sort(a, 2, 3) quick_sort(a, 9, 9) quick_sort(a, 11, 11) quick_sort(a, 2, 1) quick_sort(a, 3, 3)

More Related