Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Programming with Recursion. 2 Recursive Function Call A recursive call is a function call in which the called function is the same as the one making.

Similar presentations


Presentation on theme: "1 Programming with Recursion. 2 Recursive Function Call A recursive call is a function call in which the called function is the same as the one making."— Presentation transcript:

1 1 Programming with Recursion

2 2 Recursive Function Call A recursive call is a function call in which the called function is the same as the one making the call. In other words, recursion occurs when a function calls itself! We must avoid making an infinite sequence of function calls (infinite recursion).

3 3 Finding a Recursive Solution Each successive recursive call should bring you closer to a situation in which the answer is known. A case for which the answer is known (and can be expressed without recursion) is called a base case. Each recursive algorithm must have at least one base case, as well as the general (recursive) case

4 4 General format for many recursive functions if (some condition for which answer is known) // base case solution statement else // general case recursive function call SOME EXAMPLES...

5 5 Writing a recursive function to find n factorial DISCUSSION The function call Factorial(4) should have value 24, because that is 4 * 3 * 2 * 1. For a situation in which the answer is known, the value of 0! is 1. So our base case could be along the lines of if ( number == 0 ) return 1;

6 6 Writing a recursive function to find Factorial(n) Now for the general case... The value of Factorial(n) can be written as n * the product of the numbers from (n - 1) to 1, that is, n * (n - 1) *... * 1 or, n * Factorial(n - 1) And notice that the recursive call Factorial(n - 1) gets us “closer” to the base case of Factorial(0).

7 7 Recursive Solution int Factorial ( int number ) // Pre: number is assigned and number >= 0. { if ( number == 0)// base case return 1 ; else// general case return number * Factorial ( number - 1 ) ; }

8 8 Three-Question Method of verifying recursive functions Base-Case Question: Is there a non-recursive way out of the function? Smaller-Caller Question: Does each recursive function call involve a smaller case of the original problem leading to the base case? General-Case Question: Assuming each recursive call works correctly, does the whole function work correctly?

9 9 Another example where recursion comes naturally From mathematics, we know that 2 0 = 1 and 2 5 = 2 * 2 4 In general, x 0 = 1 and x n = x * x n-1 for integer x, and integer n > 0. Here we are defining x n recursively, in terms of x n-1

10 // Recursive definition of power function int Power ( int x, int n ) // Pre: n >= 0. x, n are not both zero // Post: Function value = x raised to the power n. { if ( n == 0 ) return 1; // base case else // general case return ( x * Power ( x, n-1 ) ) ; } Of course, an alternative would have been to use looping instead of a recursive call in the function body. 10

11 11 “Why use recursion?” Those examples could have been written without recursion, using iteration instead. The iterative solution uses a loop, and the recursive solution uses an if statement. However, for certain problems the recursive solution is the most natural solution.

12 12 Use a recursive solution when: The depth of recursive calls is relatively “shallow” compared to the size of the problem. The recursive version does about the same amount of work as the nonrecursive version. The recursive version is shorter and simpler than the nonrecursive solution. SHALLOW DEPTH EFFICIENCY CLARITY

13 13 the quick sort algorithm A.. Z A.. L M.. Z A.. F G.. L M.. R S.. Z

14 14 Before call to function Split values[first] [last] splitVal = 9 GOAL: place splitVal in its proper position with all values less than or equal to splitVal on its left and all larger values on its right 9 20 6 10 14 3 60 11

15 15 After call to function Split values[first] [splitPoint] [last] splitVal = 9 smaller values larger values 6 3 9 10 14 20 60 11

16 // Recursive quick sort algorithm template void QuickSort ( ItemType values[ ], int first, int last ) // Pre: first <= last // Post: Sorts array values[ first..last ] into ascending order { if ( first < last ) // general case {int splitPoint ; Split ( values, first, last, splitPoint ) ; // values [ first ].. values[splitPoint - 1 ] <= splitVal // values [ splitPoint ] = splitVal // values [ splitPoint + 1 ].. values[ last ] > splitVal QuickSort( values, first, splitPoint - 1 ) ; QuickSort( values, splitPoint + 1, last ); } } 16

17 Merge Sort Algorithm

18 Divide and Conquer We can use a type of a divide and conquer algorithm to sort an array We'll use what's called a merge sort We'll divide the portion of the array we are currently working on into two parts, and sort the parts, and then merge them together to finish the deal

19 Merge Sort Algorithm The merge sort algorithm is roughly as follows mergeSort(array, start, end) middle = start + end / 2 mergesort(arr, start, middle) mergesort(arr, middle+1, end) merge(arr, start, middle, end) Find a middle, sort the two halves, then merge them together

20 Merge Sort Algorithm What's missing? We need a base case, and there are two options 1) When the size of the part of the array we are working on is 1, we can consider this sorted 2) When the size of the part of the array we are working on is "small enough", use a "slower" sort to finish that portion (since recursive calls are expensive) We'll just use 1, for purposes of easier algorithm analysis, and we don't lose much anyway

21 Sorting - Merge Sort Use merge sort on the array A = [ 5, 2, 4, 6, 1, 3, 2, 6 ] 5 2 4 6 1 3 2 6 5 2 4 6 4 6 62542316 5 21 32 6 1 3 2 6 Calling “merge_sort” method

22 Sorting - Merge Sort Merging operation on sorted sequence –lengths of the sorted sequence being merged increased as the algorithm progress from bottom to top 1 2 2 3 4 5 6 6 2 4 5 6 4 6 62542316 2 51 32 6 1 2 3 6 merge merge sort on the array A = [ 5, 2, 4, 6, 1, 3, 2, 6 ]

23 Sorting - Merge Sort Algorithm: divide-and-conquer merge_sort(A, i, j) { if ( i< j ) { compute k = ( i + j ) / 2 merge_sort(A, i, k) merge_sort(A, k+1, j) return( merge the two sorted sequences to form one sorted sequence) } A ij A i k A k+1j

24 Merge Step The merge step algorithm should run as fast as possible The merge function will get the start, middle, and end of the array What it can do is create a secondary array to copy values into, and then copy those back into the original array

25 Merge Step Algorithm merge(array, start, middle, end) make temp array while neither array is empty if array[start] > array[middle] copy array[start++] into temp else copy array[middle++] into temp while not finished array is not empty copy all elements into temp copy elements of temp into array

26 Merge Step Runtime What is the runtime of the merge step? If we look at the while loops, the first one either goes from start to middle OR middle to end, with some portion of the other, while the 2nd while loop finishes the job Thus, combined, the while loops take a total time of end - start, which, in the worse case, is O(n)

27 Merge Step Code private static void merge(int[] arr, int start, int mid, int end) { int[] temp = new int[end-start+1]; int first1 = start, last1 = mid, first2 = mid+1, last2 = end; int index = 0; while (first1 <= last1 && first2 <= last2) if (arr[first1] < arr[first2]) temp[index++] = arr[first1++]; else temp[index++] = arr[first2++]; while (first1 <= last1) temp[index++] = arr[first1++]; while (first2 <= last2) temp[index++] = arr[first2++]; for (int i = 0, j = start; i < end-start+1; i++, j++) arr[j] = temp[i]; }

28 Merge Sort Code public static void mergeSort(int[] arr) { mergeSort(arr, 0, arr.length-1); } private static void mergeSort(int[] arr, int start, int end) { if (start < end) { int mid = (start + end) / 2; mergeSort(arr, start, mid); mergeSort(arr, mid+1, end); merge(arr, start, mid, end); } }

29 Merge Sort Analysis The base case is T(1) = 1, what is the recursive case for the recurrence relation? The merge step is O(n) (as we figured out before), there are two recursive calls, and 1 (insignificant) other statement T(n) = 2*T(n/2) + O(n) + 1 We showed in the last set of slides that this is O(n log n)

30 Other D&C Algorithms Quicksort (a D&C with a worst case of n 2 ) Tree traversals (linear time; this will be discussed later on in the course)

31 Summary Divide and conquer gives us recursive solutions to problems We attempt to inch closer to the solution by dividing the problem in half and doing something interesting with the result of solving the halves As with the merge sort and maximum subsequence sum algorithms, we may have to do something beyond looking at the results of the halves We can analyze divide and conquer algorithms very easily by looking at recurrence relations

32 32 Function BinarySearch( ) BinarySearch takes sorted array info, and two subscripts, fromLoc and toLoc, and item as arguments. It returns false if item is not found in the elements info[fromLoc…toLoc]. Otherwise, it returns true. BinarySearch can be written using iteration, or using recursion.

33 33 found = BinarySearch(info, 25, 0, 14 ); item fromLoc toLoc indexes 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 info 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 16 18 20 22 24 26 28 24 26 28 24 NOTE: denotes element examined

34 // Recursive definition template bool BinarySearch ( ItemType info[ ], ItemType item, int fromLoc, int toLoc ) // Pre: info [ fromLoc.. toLoc ] sorted in ascending order // Post: Function value = ( item in info [ fromLoc.. toLoc] ) {int mid ; if ( fromLoc > toLoc ) // base case -- not found return false ; else { mid = ( fromLoc + toLoc ) / 2 ; if ( info [ mid ] == item ) // base case-- found at mid return true ; else if ( item < info [ mid ] ) // search lower half return BinarySearch ( info, item, fromLoc, mid-1 ) ; else // search upper half return BinarySearch( info, item, mid + 1, toLoc ) ; } } 34


Download ppt "1 Programming with Recursion. 2 Recursive Function Call A recursive call is a function call in which the called function is the same as the one making."

Similar presentations


Ads by Google