Presentation is loading. Please wait.

Presentation is loading. Please wait.

Nothing is particularly hard if you divide it into small jobs. Henry Ford Nothing is particularly hard if you divide it into small jobs. Henry Ford.

Similar presentations


Presentation on theme: "Nothing is particularly hard if you divide it into small jobs. Henry Ford Nothing is particularly hard if you divide it into small jobs. Henry Ford."— Presentation transcript:

1

2 Nothing is particularly hard if you divide it into small jobs. Henry Ford Nothing is particularly hard if you divide it into small jobs. Henry Ford

3  Recursive in structure  Divide ▪ The problem into sub-problems that are similar to the original but smaller in size.  Conquer ▪ The sub-problems by solving them recursively. ▪ If they are small enough, just solve them in a straightforward manner.  Combine ▪ The solutions to create a solution to the original problem

4

5  Divide array into two halves, recursively sort left and right halves, then merge two halves  Mergesort  To sort an array A[p.. r]:  Divide  Divide the n-element sequence to be sorted into two subsequences of n/2 elements each  Conquer  Sort the subsequences recursively using merge sort  When the size of the sequences is 1 there is nothing more to do  Combine  Merge the two sorted subsequences to produce the sorted answer.

6  Divide it in two at the midpoint  Conquer each side in turn (by recursively sorting)  Merge two halves together 82945316

7 void Mergesort (int A[], int first, int last) { if(first < last) { int mid = (first + last)/2; Mergesort(A, first, mid); Mergesort(A, mid+1,last); Merge(A, first, mid, last); } 01234567 6231742 5 first last mid Check for base case Divide Conquer Combine

8 Merge Sort – Example 182632 64315 9 1 182632 6 4315 9 1 182632 6 4315 9 1 26 18 6 32 15 43 1 9 18 26 32 6 43 15 9 1 182632 64315 9 1 182632 61543 1 9 618 2632 1 91543 1 6 91518263243 1826 18 26 1826 32 6 6 6 182632 6 43 15 4315 9 9 1 1 9 1 4315 9 1 182632 64315 9 1 18 26 6 32 6 2632 18 15 43 1 9 1 9 15 43 1 6 91518 26 32 43 Original Sequence Sorted Sequence

9 j Merge Function 6 82632 1 94243 A k 6 826 32 1 94243 k k k k k k i i i i i j j j j 6 82632 1 94243 1 6 8 926324243 k B C void Merge(int A[], int first, int mid, int last) { int n1, n2, i, j, k; n1 = mid - first + 1; n2 = last - mid; int B[n1]; int C[n2]; for (i=0; i< n1;i++) B[i] = A[first +i]; for (j=0; j< n2;j++) C[j] = A[mid +j+1]; i = 0; j = 0; k = first; while(i< n1 && j < n2) { if( B[i] <= C[j]) { A[k] = B[i]; i= i+1; } else { A[k] = C[j]; j= j+1; } k= k+1; } if(i < n1) { while(i < n1) { A[k] = B[i]; k =k+1; i=i+1; } { if(j < n2) { while(j < n2) { A[k] = C[j]; k =k+1; j=j+1; } first midlast Declaring auxiliary arrays of size n1 and n2 Moving element to auxiliary arrays Compare two elements, move one of them to the original array constant cost. k Copying the remaining elements to original array.

10 j Analysis of Merge Function 6 82632 1 94243 A k 6 826 32 1 94243 k k k k k k i i i i i j j j j 6 82632 1 94243 1 6 8 926324243 k B C void Merge(int A[], int first, int mid, int last) { int n1, n2, i, j, k; n1 = mid - first + 1; n2 = last - mid; int B[n1]; int C[n2]; for (i=0; i< n1;i++) B[i] = A[first +i]; for (j=0; j< n2;j++) C[j] = A[mid + j+1]; i = 0; j = 0; k = first; while(i< n1 && j < n2) { if( B[i] <= C[j]) { A[k] = B[i]; i= i+1; } else { A[k] = C[j]; j= j+1; } k= k+1; } if(i < n1) { while(i < n1) { A[k] = B[i]; k =k+1; i=i+1; } { if(j < n2) { while(j < n2) { A[k] = C[j]; k =k+1; j=j+1; } first midlast Declaring auxiliary arrays of size n1 and n2 O(1) Moving element to auxiliary arrays O(n) O(1) Compare two elements, move one of them to the original array constant cost. k Copying the remaining elements to original array. O(n)

11  So far we have seen that it takes  O(n) time to merge two subarrays of size n/2  O(n) time to merge four subarrays of size n/4 into two subarrays of size n/2  O(n) time to merge eight subarrays of size n/8 into four subarrays of size n/4  Etc.  How many levels deep do we have to proceed?  How many times can we divide an array of size n into two halves?  O(log n)

12  So if our recursion goes log n levels deep......and we do O(n) work at each level......our total time is: log n * O(n)... ...or in other words, O(n log n)  For large arrays, this is much better than Bubblesort, Selection sort, or Insertion sort, all of which are O(n 2 )  Not in place  Mergesort does, however, require a “workspace” array as large as our original array (O(n) extra space)

13 void Mergesort (int A[], int first, int last) { if(first < last) { int mid = (first + last)/2; Mergesort(A, first, mid); Mergesort(A, mid+1,last); Merge(A, first, mid, last); } Check for base case Divide Conquer Combine Running time T(n) of Merge Sort: computing the middle takes  (1)  (1) solving 2 sub-problems takes 2T(n/2) merging n elements takes  (n) Total: T(n) =  (1) if n = 1 T(n) = 2T(n/2) +  (n) if n > 1  T(n) =  (n lg n)

14  Running time of Merge Sort: T(n) =  (1) if n = 1 T(n) = 2T(n/2) +  (n) if n > 1  Rewrite the recurrence as T(n) = c if n = 1 T(n) = 2T(n/2) + cn if n > 1 c > 0: Running time for the base case and time per array element for the divide and combine steps.

15 For the original problem, we have a cost of cn, plus two subproblems each of size (n/2) and running time T(n/2). cn T(n/2) Each of the size n/2 problems has a cost of cn/2 plus two subproblems, each costing T(n/4). cn cn/2 T(n/4) Cost of divide and merge. Cost of sorting subproblems.

16 Comp 122 Continue expanding until the problem size reduces to 1. cn cn/2 cn/4 cccccc lg n cn Total : cnlgn+cn

17 Continue expanding until the problem size reduces to 1. cn cn/2 cn/4 cccccc Each level has total cost cn. Each time we go down one level, the number of subproblems doubles, but the cost per subproblem halves  cost per level remains the same. There are lg n + 1 levels, height is lg n. (Assuming n is a power of 2.) Can be proved by induction. Total cost = sum of costs at each level = (lg n + 1)cn = cnlgn + cn =  (n lgn).

18

19  Partition array into items that are “small” and items that are “large”, then recursively sort the two sets  Quicksort  Divide  Partition array into left and right sub-arrays ▪ Choose an element of the array, called pivot ▪ The elements in left sub-array are all less than pivot ▪ Elements in right sub-array are all greater than pivot  Conquer  Recursively sort left and right sub-arrays  Combine  Trivial: the arrays are sorted in place  No additional work is required to combine them  The entire array is now sorted

20  A key step in the Quicksort algorithm is partitioning the array  We choose some (any) number p in the array to use as a pivot  We partition the array into three parts: p numbers less than p numbers greater than or equal to p p

21 13 81 92 43 65 3157 26 75 0 S select pivot value 13 81 92 43 65 31 5726 75 0 S1S1 S2S2 partition S 13433157260 S1S1 819275 65 S2S2 QuickSort(S 1 ) 1343315726065819275 S S is sorted QuickSort(S 2 )

22 void quicksort(int array[], int left, int right) { if (left < right) { int p = partition(array, left, right); quicksort(array, left, p - 1); quicksort(array, p + 1, right); } Check for base case Divide Conquer Combine

23 int partition(int a[], int left, int right) { int p = a[left], l = left + 1, r = right; while (l < r) { while (l < right && a[l] < p) l++; while (r > left && a[r] >= p) r--; if (l < r) { swap(a[l], a[r]); } a[left] = a[r]; a[r] = p; return r; }

24 We are given array of n integers to sort: 402010806050730100

25 There are a number of ways to pick the pivot element. In this example, we will use the first element in the array: 402010806050730100

26 Given a pivot, partition the elements of the array such that the resulting array consists of: 1. One sub-array that contains elements < pivot 2. Another sub-array that contains elements >= pivot The sub-arrays are stored in the original data array. Partitioning loops through, swapping elements below/above pivot.

27 402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] l r 1.while (l<r)

28 402010806050730100 pivot_index = 0 l r 1.while (l<r) 2.{while (l < right && a[l] < p ) l ++; [0] [1] [2] [3] [4] [5] [6] [7] [8]

29 402010806050730100 pivot_index = 0 l r 1.while (l<r) 2.{while (l < right && a[l] < p ) l ++; [0] [1] [2] [3] [4] [5] [6] [7] [8]

30 402010806050730100 pivot_index = 0 l r 1.while (l<r) 2.{while (l < right && a[l] < p ) l ++; [0] [1] [2] [3] [4] [5] [6] [7] [8]

31 402010806050730100 pivot_index = 0 l r 1.while(l<r) 2.{while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; [0] [1] [2] [3] [4] [5] [6] [7] [8]

32 402010806050730100 pivot_index = 0 l r 1.while(l<r) 2.{while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; [0] [1] [2] [3] [4] [5] [6] [7] [8]

33 402010806050730100 pivot_index = 0 l r 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } [0] [1] [2] [3] [4] [5] [6] [7] [8]

34 402010306050780100 pivot_index = 0 l r 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } [0] [1] [2] [3] [4] [5] [6] [7] [8]

35 402010306050780100 pivot_index = 0 l r 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } [0] [1] [2] [3] [4] [5] [6] [7] [8]

36 402010306050780100 pivot_index = 0 l r 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } [0] [1] [2] [3] [4] [5] [6] [7] [8]

37 402010306050780100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

38 402010306050780100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

39 402010306050780100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

40 402010306050780100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

41 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

42 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

43 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

44 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

45 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

46 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

47 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

48 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

49 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

50 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) }

51 402010307506080100 pivot_index = 0 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } a[left] = a[r]; a[r] = p; return r;

52 720103040506080100 pivot_index = 4 l r [0] [1] [2] [3] [4] [5] [6] [7] [8] 1.while (l < r) 2.{ while (l < right && a[l] < p) l ++; 3. while (r > left &&a[r] >= p) r--; 4. if ( l < r ) swap ( a[l], a[r] ) } a[left] = a[r]; a[r] = p; return r;

53 720103040506080100 <= pivot> pivot

54 720103040506080100 < data[pivot]> = data[pivot] [0] [1] [2] [3] [4] [5] [6] [7] [8]

55 Example of partitioning choose pivot: 4 3 6 9 2 4 3 1 2 1 8 9 3 5 6 search: 4 3 6 9 2 4 3 1 2 1 8 9 3 5 6 swap: 4 3 3 9 2 4 3 1 2 1 8 9 6 5 6 search: 4 3 3 9 2 4 3 1 2 1 8 9 6 5 6 swap: 4 3 3 1 2 4 3 1 2 9 8 9 6 5 6 search: 4 3 3 1 2 4 3 1 2 9 8 9 6 5 6 swap: 4 3 3 1 2 2 3 1 4 9 8 9 6 5 6 search: 4 3 3 1 2 2 3 1 4 9 8 9 6 5 6 (left > right) swap with pivot: 1 3 3 1 2 2 3 4 4 9 8 9 6 5 6

56 int partition(int a[], int left, int right) { int p = a[left], l = left + 1, r = right; while (l < r) { while (l < right && a[l] < p) l++; while (r > left && a[r] >= p) r--; if (l < r) { swap(a[l], a[r]); } a[left] = a[r]; a[r] = p; return r; } O(n)

57 void quicksort(int array[], int left, int right) { if (left < right) { int p = partition(array, left, right); quicksort(array, left, p - 1); quicksort(array, p + 1, right); } Check for base case Divide Conquer Combine  (1)  (n)  (0)

58  Suppose each partition operation divides the array almost exactly in half  Then the depth of the recursion in log 2 n.  At each level of the recursion, all the partitions at that level do work that is linear in n.  O(log 2 n) * O(n) = O(n log 2 n)  Hence in the average case, quicksort has time complexity O(n log 2 n)

59

60 void quicksort(int array[], int left, int right) { if (left < right) { int p = partition(array, left, right); quicksort(array, left, p - 1); quicksort(array, p + 1, right); } Check for base case Divide Conquer Combine  (1)  (n)  (0) Total: T(n) =  (1) if n = 1 T(n) = 2T(n/2) +  (n) if n > 1  T(n) =  (n lg n) 2T(n/2)

61  Best-case partitioning  Partitioning produces two regions of size n/2  Recurrence: q=n/2 T(n) = 2T(n/2) +  (n) T(n) =  (nlgn) (Master theorem)

62  In the worst case, partitioning always divides the size n array into these three parts:  A length one part, containing the pivot itself  A length zero part, and  A length n-1 part, containing everything else  We don’t recur on the zero-length part  Recurring on the length n-1 part requires (in the worst case) recurring to depth n.

63

64  Worst-case partitioning  One region has zero element and the other has n – 1 elements  Maximally unbalanced  Recurrence: q=1 T(n) = T(n – 1) = T(0) +  (n) T(1) =  (1) T(n) = T(n – 1) + n n n - 1 n - 2 n - 3 2 1 0 0 0 0 0 n n n - 1 n - 2 n - 3 2 1  (n 2 ) When does the worst case happen?

65 void quicksort(int array[], int left, int right) { if (left < right) { int p = partition(array, left, right); quicksort(array, left, p - 1); quicksort(array, p + 1, right); } Check for base case Divide Conquer Combine  (1)  (n)  (0) Total: T(n) =  (1) if n = 1 T(n) = T(n-1)  (n) if n > 1  T(n) =  (n 2 ) T(n-1)+T(0) =T(n-1)

66  Assume first element is chosen as pivot.  Assume we get array that is already in order: 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index

67 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index

68 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index

69 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index

70 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index

71 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index

72 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index

73 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] > data[pivot]<= data[pivot]

74  9-to-1 proportional split Q(n) = Q(9n/10) + Q(n/10) + n

75  Assume  Each of the sizes for S1 is equally likely  This assumption is valid for our pivoting (median-of-three) strategy  On average, the running time is O(N log N)

76  Assume that keys are random, uniformly distributed.  Best case and average case running time: O(n log n)  Worst case running time?  Recursion: 1.Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2.Quicksort each sub-array  Depth of recursion tree? O(n)  Number of accesses per partition? O(n)

77  Assume that keys are random, uniformly distributed.  Best case running time: O(n log n)  Average case running time: O(n log n)  Worst case running time: O(n 2 )!!! What can we do to avoid worst case?

78 Pick median value of three elements from data array: data[0], data[n/2], and data[n-1]. Use this median value as pivot. 8149035276 0123456789 61490352 6 8 Median of 0, 6, 8 is 6. Pivot is 6 Choose the pivot as the median of three

79  One implementation (there are others)  median3 finds pivot and sorts left, center, right ▪ Median3 takes the median of leftmost, middle, and rightmost elements ▪ An alternative is to choose the pivot randomly (need a random number generator; “expensive”) ▪ Another alternative is to choose the first element (but can be very bad. Why?)  Swap pivot with the first element

80  Best case: split in the middle — Θ( n log n)  Worst case: sorted array! — Θ( n 2 )  Average case: random arrays — Θ( n log n)  Memory requirement?  In-place sorting algorithm  Considered as the method of choice for internal sorting for large files (n ≥ 10000)

81  Best case: split in the middle — Θ( n log n)  Worst case: sorted array! — Θ( n 2 )  Average case: random arrays — Θ( n log n)  Considered as the method of choice for internal sorting for large files (n ≥ 10000)  Improvements:  better pivot selection: median of three partitioning avoids worst case in sorted files  switch to insertion sort on small subfiles  elimination of recursion these combine to 20-25% improvement

82  For very small arrays, quicksort does not perform as well as insertion sort  how small depends on many factors, such as the time spent making a recursive call, the compiler, etc  Do not use quicksort recursively for small arrays  Instead, use a sorting algorithm that is efficient for small arrays, such as insertion sort

83  Not stable because of long distance swapping.  No iterative version (without using a stack).  Pure quicksort not good for small arrays.  “In-place”, but uses auxiliary storage because of recursive call (O(logn) space).  O(n log n) average case performance, but O(n 2 ) worst case performance.


Download ppt "Nothing is particularly hard if you divide it into small jobs. Henry Ford Nothing is particularly hard if you divide it into small jobs. Henry Ford."

Similar presentations


Ads by Google