1 programming with recursion. 2 recursive function call a recursive call is a function call in which...

34
1 Programming with Recursion

Upload: buddy-green

Post on 31-Dec-2015

234 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: 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

1

Programming with Recursion

Page 2: 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

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

Page 3: 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

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

Page 4: 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

4

General format formany recursive functions

if (some condition for which answer is known) // base case

solution statement

else // general case

recursive function call

SOME EXAMPLES . . .

Page 5: 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

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;

Page 6: 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

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

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

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

}

Page 8: 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

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?

Page 9: 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

9

Another example where recursion comes naturally

• From mathematics, we know that

20 = 1 and 25 = 2 * 24

• In general,

x0 = 1 and xn = x * xn-1

for integer x, and integer n > 0.

• Here we are defining xn recursively, in terms of xn-1

Page 10: 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

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

Page 11: 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

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.

Page 12: 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

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

Page 13: 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

13

the quick sort algorithm

A . . Z

A . . L M . . Z

A . . F G . . L M . . R S . . Z

Page 14: 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

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

Page 15: 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

15

After call to function Split

values[first] [splitPoint] [last]

splitVal = 9

smaller values larger values

6 3 9 10 14 20 60 11

Page 16: 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

// Recursive quick sort algorithm

template <class ItemType >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

Page 17: 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

Merge Sort Algorithm

Page 18: 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

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

Page 19: 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

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

Page 20: 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

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

Page 21: 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

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

625 4 231 6

5 2 1 3 2 6

1 3 2 6

Calling “merge_sort” method

Page 22: 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

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

625 4 231 6

2 5 1 3 2 6

1 2 3 6

merge

merge merge

merge merge merge merge

merge sort on the array A = [ 5, 2, 4, 6, 1, 3, 2, 6 ]

Page 23: 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

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

i j

A

i k

A

k+1 j

Page 24: 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

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

Page 25: 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

Merge Step Algorithm

merge(array, start, middle, end)make temp arraywhile neither array is empty

if array[start] > array[middle]copy array[start++] into temp

else copy array[middle++] into tempwhile not finished array is not empty

copy all elements into tempcopy elements of temp into array

Page 26: 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

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)

Page 27: 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

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++];elsetemp[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];

}

Page 28: 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

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

}}

Page 29: 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

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)

Page 30: 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

Other D&C Algorithms

• Quicksort (a D&C with a worst case of n2)

• Tree traversals (linear time; this will be discussed later on in the course)

Page 31: 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

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

Page 32: 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

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.

Page 33: 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

33

found = BinarySearch(info, 25, 0, 14 );

item fromLoc toLocindexes

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

Page 34: 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

// Recursive definition

template<class ItemType>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