Presentation is loading. Please wait.

Presentation is loading. Please wait.

Examples of Recursion Data Structures in Java with JUnit ©Rick Mercer.

Similar presentations


Presentation on theme: "Examples of Recursion Data Structures in Java with JUnit ©Rick Mercer."— Presentation transcript:

1 Examples of Recursion Data Structures in Java with JUnit ©Rick Mercer

2 Converting Decimal Numbers to other bases  Problem: Convert a decimal (base 10) number into other bases method Call Return method Call Return convert(99, 2) 1100011 convert(99, 2) 1100011 convert(99, 3) 10200 convert(99, 3) 10200 convert(99, 4) 1203 convert(99, 4) 1203 convert(99, 5) 344 convert(99, 5) 344 convert(99, 6) 243 convert(99, 6) 243 convert(99, 7) 201 convert(99, 7) 201 convert(99, 8) 143 convert(99, 8) 143 convert(99, 9) 120 convert(99, 9) 120

3 Digits are multiplied by powers of the base 10, 8, 2, or whatever  First: converting from other bases to decimal  Decimal numbers multiply digits by powers of 10 9507 10 = 9 x 10 3 + 5 x 10 2 + 0 x 10 1 + 7 x 10 0  Octal numbers powers of 8 1567 8 = 1 x 8 3 + 5 x 8 2 + 6 x 8 1 + 7 x 8 0 = 512 + 320 + 48 + 7 = 887 10 = 512 + 320 + 48 + 7 = 887 10  Binary numbers powers of 2 1101 2 = 1 x 2 3 + 1 x 2 2 + 0 x 2 1 + 1 x 2 0 = 8 + 4 + 0 + 1 = 13 10 = 8 + 4 + 0 + 1 = 13 10

4 Converting base 10 to base 2 1) divide number (5) by new base(2), write remainder (1) 2) divide quotient (2), write new remainder (0) to left 3) divide quotient (1), write new remainder (1) to left _ _ 2_ _ _ 2_ 2 ) 5 Remainder = 1 2 ) 5 Remainder = 1 __1_ __1_ 2 ) 2 Remainder = 0 2 ) 2 Remainder = 0 __0_ __0_ 2 ) 1 Remainder = 1 2 ) 1 Remainder = 1 Stop when the quotient is 0 5 10 = 101 2 Stop when the quotient is 0 5 10 = 101 2 Print remainders in reverse order

5 Converting base 10 to base 8 1) divide number by new base (8), write remainder (1) 2) divide quotient (2), write new remainder (0) to left 3) divide quotient (1), write new remainder (1) to left _12_ _12_ 8 )99 Remainder = 3 8 )99 Remainder = 3 __1_ __1_ 8 )12 Remainder = 4 8 )12 Remainder = 4 __0_ __0_ 8 ) 1 Remainder = 1 8 ) 1 Remainder = 1 Stop when the quotient is 0 99 10 = 143 8 Print remainders in reverse order

6 Possible Solutions  We could either  store remainders in an array and reverse it or  write out the remainders in reverse order  have to postpone the output until we get quotient = 0  store result as a String (like a Recursion assignment)  Iterative Algorithm while the decimal number > 0 { while the decimal number > 0 { Divide the decimal number by the new base Divide the decimal number by the new base Set the decimal number = decimal number divided by the base Set the decimal number = decimal number divided by the base Store the remainder to the left of any preceding remainders Store the remainder to the left of any preceding remainders }

7 Recursive algorithm Base Case -- Recursive Case  Base case  if decimal number being converted = 0  do nothing (or return "")  Recursive case  if decimal number being converted > 0  solve a simpler version of the problem –use the quotient as the argument to the next call  store the current remainder (number % base) in the correct place

8 One solution assertEquals("14", rf.convert(14, 10)); assertEquals("1100011", rf.convert(99, 2)); assertEquals("143", rf.convert(99, 8)); assertEquals("98", rf.convert(98, 10)); // 9*10+8 public String convert(int num, int base) { if (num == 0) if (num == 0) return ""; return ""; else else return convert(num/base, base) + (num%base); return convert(num/base, base) + (num%base);}

9 Hexadecimal, something we see as Computer Scientists  Convert this algorithm to handle all base up through hexadecimal (base 16)  10 = A  11 = B  12 = C  13 = D  14 = E  15 = F

10 Quicksort: O(n log n) Sorting  Quicksort was discovered by Tony Hoare 1962  Here is an outline of his famous algorithm:  Pick one item from the array--call it the pivot  Partition the items in the array around the pivot so all elements to the left are  to the pivot and all elements to the right are greater than the pivot  Use recursion to sort the two partitions a snapshot pivot partition: items > pivot partition 1: items  pivot

11 Before and After  Let's sort integers  Pick the leftmost one (27) as the pivot value  The array before call to partition(a, 0, n-1)  Array looks like this after first partition is done 27 14 9 22 8 41 56 31 14 53 99 11 2 24 24 14 9 22 8 14 11 2 27 53 99 56 31 41 pivotitems < pivotitems > pivot

12 The partition method  p artition divvies up a around the split and returns the position of the split, an integer in the range of 0..n-1  The postcondition of partition: a[first]..a[split-1] <= a[split] && a[split+1]..a[last] > a[split]  Notes:  May be more than 1 element equal to the pivot  Put them in left partition could have been the right

13 Recursive call to sort smaller part of the array quickSort(a, split+1, last); // sort right  QuickSort the right. At some point  Pivot will be 53  And the left portion will be sorted 24 14 9 22 8 14 11 2 27 53 99 56 31 41 2 8 9 11 14 14 22 24 27 31 41 53 99 56 pivot items < pivotitems > pivot left is already sorted, begin to sort part to the right of split

14 Complete the sort // sort left and right around new split // sort left and right around new split quickSort(a, first, split-1); quickSort(a, first, split-1); // sort right // sort right quickSort(a, split+1, last); quickSort(a, split+1, last); 2 8 9 11 14 14 22 24 27 31 41 53 99 56 2 8 9 11 14 14 22 24 27 31 41 53 56 99 Entire array is now sorted

15 Start Over (i ==1) Start Over (i ==1)  Now let's back up and start with empty partitions int partition(int a[], int first, int last) { int lastSmall = first; int lastSmall = first; int i = (first + 1); // Beginning of unknowns int i = (first + 1); // Beginning of unknowns  Compare all items from a[i]..a[last]  if a[i] > a[first] (the pivot), do nothing  if a[i] <= a[first], swap a[lastSmall+1] with a[i] 27 41 14 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items (all are unknown--except first)

16 Result of the 1st loop iteration(i==2) 27 41 14 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot  The following array shows no changes were made in the array since a[i] <= a[first] was false  So simply add 1 to i (i++)--create 2 partitions  Now partition 1 has one element (the pivot 27) and partition 2 has 1 element (41)

17 Result of the 2nd loop iteration(i==3) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot  The following array shows a swap was made in the array since a[i] <= a[first] was true (14 < 27)  a[i] (14) is swapped with a[lastSmall+1] (41)  lastSmall gets incremented to point to the last element in partition 1  i gets incremented to reference 56

18 Result of the 3rd loop iteration(i==4) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot  The following array shows no swap was made in the array since a[i] <= a[first] was false  lastSmall does NOT get incremented  i gets incremented to reference 31

19 Result of the 4th loop iteration(i==5) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot  The following array shows no swap was made in the array since a[i] <= a[first] was false  lastSmall does NOT get incremented  i gets incremented to reference 9

20 Result of the 5th loop iteration(i==6) 27 14 9 56 31 41 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot  The following array shows a swap was made in the array since a[i] <= a[first] was true (9 < 27)  a[i] (9) is swapped with a[lastSmall+1] (41)  lastSmall gets incremented to point to the last element in partition 1  i++ points to the first unknown (22)

21 27 14 9 22 31 41 56 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot i == 7

22 27 14 9 22 8 41 56 31 14 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 8

23 27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 9

24 27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 10

25 27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 11

26 27 14 9 22 8 14 11 31 41 53 99 56 2 24 first lastSmall i unknown partition 1: all items pivot i == 12

27 27 14 9 22 8 14 11 2 41 53 99 56 31 24 first lastSmall i unknown partition 1: all items pivot i == 13

28 Result of the 14th loop iteration(i==14) 27 14 9 22 8 14 11 2 24 53 99 56 31 41 first lastSmall i partition 1: all items pivot  The following array shows what happens after traversing the entire array with this loop (i>last): for (i = first + 1; i <= last; i++) { if(a[i] <= a[first] ) { if(a[i] <= a[first] ) { lastSmall++; lastSmall++; swapElements(a, lastSmall, i); swapElements(a, lastSmall, i); } }

29 Post Loop Detail  Now place the pivot into where we expect the pivot to be: in-between the two partitions swapElements( a, first, lastSmall ); swapElements( a, first, lastSmall );  Then we can return lastSmall for the next call return lastSmall; return lastSmall; 24 14 9 22 8 14 11 2 27 53 99 56 31 41 first lastSmall (pivot position) partition 1: all items pivot

30 quickSort is called like this: quickSort(a, 0, n-1) void quickSort(int a[], int first, int last) { void quickSort(int a[], int first, int last) { // precondition: a is an array to be sorted from // precondition: a is an array to be sorted from // a[first]..a[last] // a[first]..a[last] if(first >= last) if(first >= last) return; // Done: we have an empty array return; // Done: we have an empty array // The difficult algorithm is in partition // The difficult algorithm is in partition int split = partition ( a, first, last ); int split = partition ( a, first, last ); // Recursively Quicksort left, then right // Recursively Quicksort left, then right quickSort(a, first, split-1); // sort left quickSort(a, first, split-1); // sort left quickSort(a, split+1, last); // sort right quickSort(a, split+1, last); // sort right // post: the array a is sorted // post: the array a is sorted }

31 Analyzing Quicksort  The critical statement happens in the comparison of the for loop of the partition function if(a[i] <= a[first]) if(a[i] <= a[first])  So how many times is partition called?  And what are the values for first and last (# comparisons)?  If the pivot element is near the mode, we don't have many calls to QuickSort, it is O(log n)

32 The best of Quicksort, the worst of Quicksort  In the best case (1st element is always middle value) with 7 elements, call partition 3 times first == 0, last == 6 // 6 comparisons first == 0, last == 6 // 6 comparisons first == 0, last == 2 // 2 comparisons first == 0, last == 2 // 2 comparisons first == 4, last == 6 // 2 comparisons first == 4, last == 6 // 2 comparisons  In the worst case, (sorted array), with 7 elements, partition is called first == 0, last == 6 // 6 comparisons first == 0, last == 6 // 6 comparisons first == 1, last == 6 // 5 comparisons first == 1, last == 6 // 5 comparisons first == 2, last == 6 // 4 comparisons first == 2, last == 6 // 4 comparisons first == 3, last == 6 // 3 comparisons first == 3, last == 6 // 3 comparisons first == 4, last == 6 // 2 comparisons first == 4, last == 6 // 2 comparisons first == 5, last == 6 // 1 comparison first == 5, last == 6 // 1 comparison

33 Best Case: [ 4, 1, 3, 2, 6, 5, 7 ] [ 4, 1, 3, 2, 6, 5, 7 ] [ 2, 1, 3, 4, 6, 5, 7 ] [ 2, 1, 3, 4, 6, 5, 7 ] [ 2, 1, 3] [ 6, 5, 7 ] [ 2, 1, 3] [ 6, 5, 7 ] [ 1, 2, 3] [ 5, 6, 7 ] [ 1, 2, 3] [ 5, 6, 7 ] [1] [3] [5] [7] [1] [3] [5] [7]

34 Worst Case [ 1, 2, 3, 4, 5, 6, 7] [] [2, 3, 4, 5, 6, 7] [] [2, 3, 4, 5, 6, 7] [] [3, 4, 5, 6, 7] [] [3, 4, 5, 6, 7] [] [4, 5, 6, 7] [] [4, 5, 6, 7] [] [5, 6, 7] [] [5, 6, 7] [] [6, 7] [] [6, 7] [] [7] [] [7] [] [] [] []

35 The Best and Worst continued  So in the worst case, partition is called n-1 times: (n-1)+(n-2)+... + 1 comparisons = O(n 2 )  The worst case of Quicksort may be the same as Selection Sort, which is O(n 2 )  Quicksort is used because of its best and average cases


Download ppt "Examples of Recursion Data Structures in Java with JUnit ©Rick Mercer."

Similar presentations


Ads by Google