1 / 28

Sorting Arrange keys in ascending or descending order.

Sorting Arrange keys in ascending or descending order. One of the most fundamental problems. First computer program was a sorting program (ENIAC, Univ. of Penn.) Studied: selection sort, insertion sort, merge sort (?) and heap sort. Recall two basic sorting algorithms: selection sorting

joy-short
Download Presentation

Sorting Arrange keys in ascending or descending order.

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. Sorting Arrange keys in ascending or descending order. One of the most fundamental problems. First computer program was a sorting program (ENIAC, Univ. of Penn.) Studied: selection sort, insertion sort, merge sort (?) and heap sort

  2. Recall two basic sorting algorithms: selection sorting insertion sorting We will revisit the applet at: http://math.hws.edu/TMCM/java/xSortLab/

  3. Merge sorting In lecture 2, we studied the merging step. Merging: Take two sorted arrays and combine them into one sorted array. Merge sorting and heap sorting are two algorithms that take O(n log n) time in the worst-case. (best possible)

  4. Code for merging step void merge( vector<Comparable> & a, vector<Comparable> & tmpArray,int leftPos, int rightPos, int rightEnd ) { int leftEnd = rightPos - 1; int tmpPos = leftPos; int numElements = rightEnd - leftPos + 1; // Main loop while( leftPos <= leftEnd && rightPos <= rightEnd ) if( a[ leftPos ] <= a[ rightPos ] ) tmpArray[ tmpPos++ ] = a[ leftPos++ ]; else tmpArray[ tmpPos++ ] = a[ rightPos++ ];

  5. while( leftPos <= leftEnd )// Copy rest of first half tmpArray[ tmpPos++ ] = a[ leftPos++ ]; while( rightPos <= rightEnd )//Copy rest of right half tmpArray[ tmpPos++ ] = a[ rightPos++ ]; // Copy tmpArray back for( int i = 0; i < numElements; i++, rightEnd-- ) a[ rightEnd ] = tmpArray[ rightEnd ]; }

  6. Merge sorting algorithm Recursive version of merge sorting: To sort the array A between indices low and high: if (high == low) return; mid = (low + high) /2; recursively sort A between indices low and mid; recursively sort A between indices mid+1 and high; merge the two sorted halves.

  7. Merge sorting - Code void mergeSort( vector<Comparable> & a, vector<Comparable> & tmpArray, int left, int right ) { if( left < right ) { int center = ( left + right ) / 2; mergeSort( a, tmpArray, left, center ); mergeSort( a, tmpArray, center + 1, right ); merge( a, tmpArray, left, center + 1, right ); } }

  8. Quicksort - Introduction • Fastest known sorting algorithm in practice • Average case: O(N log N) • Worst case: O(N2) • But, the worst case rarely occurs. • Another divide-and-conquer recursive algorithm like mergesort

  9. Quicksort S • Divide step: • Pick any element (pivot) v in S • Partition S – {v} into two disjoint groups • S1 = {x  S – {v} | x v} • S2 = {x  S – {v} | x  v} • Conquer step: recursively sort S1 and S2 • Combine step: combine the sorted S1, followed by v, followed by the sorted S2 v v S1 S2

  10. Example: Quicksort

  11. Example: Quicksort...

  12. Pseudocode Input: an array A[p, r] Quicksort (A, p, r) { if (p < r) { q = Partition (A, p, r) //q is the position of the pivot element Quicksort (A, p, q-1) Quicksort (A, q+1, r) } }

  13. Partitioning • Partitioning • Key step of quicksort algorithm • Goal: given the picked pivot, partition the remaining elements into two smaller sets • Many ways to implement • Even the slightest deviations may cause surprisingly bad results. • We will learn an easy and efficient partitioning strategy here. • How to pick a pivot will be discussed later

  14. 19 6 j i Partitioning Strategy • Want to partition an array A[left .. right] • First, get the pivot element out of the way by swapping it with the last element. (Swap pivot and A[right]) • Let i start at the first element and j start at the next-to-last element (i = left, j = right – 1) swap 6 5 6 4 3 12 19 5 6 4 3 12 pivot

  15. 19 19 6 6 j j i i Partitioning Strategy • Want to have • A[p] <= pivot, for p < i • A[p] >= pivot, for p > j • When i < j • Move i right, skipping over elements smaller than the pivot • Move j left, skipping over elements greater than the pivot • When both i and j have stopped • A[i] >= pivot • A[j] <= pivot 12 5 6 4 3 5 6 4 3 12

  16. 19 19 6 6 j j i i Partitioning Strategy • When i and j have stopped and i is to the left of j • Swap A[i] and A[j] • The large element is pushed to the right and the small element is pushed to the left • After swapping • A[i] <= pivot • A[j] >= pivot • Repeat the process until i and j cross swap 5 6 4 3 12 5 3 4 6 12

  17. 19 19 19 6 6 6 j j j i i i Partitioning Strategy 5 3 4 6 12 • When i and j have crossed • Swap A[i] and pivot • Result: • A[p] <= pivot, for p < i • A[p] >= pivot, for p > i 5 3 4 6 12 5 3 4 6 12 http://math.hws.edu/TMCM/java/xSortLab/

  18. Implementation of partitioning step int partition(A, left, right){ int pivot = A[right]; int i = left, j = right-1; for (; ;) { while (a[i] < pivot && i <= right) i++; while (pivot < a[j] && j >= left) j--; if (i < j) {swap(a[i], a[j]); i++; j--; } else break; } swap(A[i], A[right]); return i; }

  19. Small arrays • 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

  20. Picking the Pivot • Use the first element as pivot • if the input is random, then we can choose the key in position A[right] as pivot. • if the input is sorted (straight or reverse) • all the elements go into S2 (or S1) • this happens consistently throughout the recursive calls • Results in O(n2) behavior (Analyze this case later) • Choose the pivot randomly • generally safe • random number generation can be expensive

  21. Picking the Pivot • Use the median of the array • Partitioning always cuts the array into roughly half • An optimal quicksort (O(N log N)) • However, hard to find the exact median

  22. Pivot: median of three • We will use median of three • Compare just three elements: the leftmost, rightmost and center • Swap these elements if necessary so that • A[left] = Smallest • A[right] = Largest • A[center] = Median of three • Pick A[center] as the pivot • Swap A[center] and A[right – 1] so that pivot is at second last position (why?) median3

  23. Pivot: median of three Code for partitioning with median of three pivot:

  24. 6 6 13 13 13 13 2 5 2 5 6 6 5 2 5 2 pivot pivot 19 Pivot: median of three A[left] = 2, A[center] = 13, A[right] = 6 6 4 3 12 19 Swap A[center] and A[right] 6 4 3 12 19 6 4 3 12 19 Choose A[center] as pivot Swap pivot and A[right – 1] 6 4 3 12 Note we only need to partition A[left + 1, …, right – 2]. Why?

  25. Implementation of partitioning step • Works only if pivot is picked as median-of-three. • A[left] <= pivot and A[right] >= pivot • Thus, only need to partition A[left + 1, …, right – 2] • j will not run past the end • because a[left] <= pivot • i will not run past the end • because a[right-1] = pivot

  26. Main Quicksort Routine Choose pivot Partitioning Recursion For small arrays

  27. Quicksort Faster than Mergesort • Both quicksort and mergesort take O(N log N) in the average case. • Why is quicksort faster than mergesort? • The inner loop consists of an increment/decrement (by 1, which is fast), a test and a jump. • Mergesort involves a large number of data movements. • Quicksort is done in-place.

  28. Performance of quicksort • Worst-case: takes O(n2) time. • Average-case: takes O(n log n) time. • On typical inputs, quicksort runs faster than other algorithms. • Compare various sorting algorithms at: http://www.geocities.com/siliconvalley/network/1854/Sort1.html

More Related