Close
Register
Close Window

Show Source |    | About   «  30.17. Sorting Part 1   ::   Contents   ::   30.19. File Processing and Buffer Pools  »

30.18. Sorting Part 2

30.18.1. Sorting Part 2

30.18.1.1. Shellsort

30.18.1.2. Shellsort (2)

void shellsort(Comparable[] A) {
  for (int i=A.length/2; i>2; i/=2) // For each increment
    for (int j=0; j<i; j++)         // Sort each sublist
      inssort2(A, j, i);
  inssort2(A, 0, 1);     // Could call regular inssort here
}

/** Modified Insertion Sort for varying increments */
void inssort2(Comparable[] A, int start, int incr) {
  for (int i=start+incr; i<A.length; i+=incr)
    for (int j=i; (j>=incr) && (A[j].compareTo(A[j-incr]) < 0); j-=incr)
      swap(A, j, j-incr);
}
void shellsort(Comparable* A[], int n) {
  for (int i = n/2; i > 2; i /= 2)  //For each increment
    for (int j = 0; j < i; j++)  //Sort each sublist
      inssort2(A, j, i, n);
    inssort2(A, 0, 1, n);
}

// Modified Insertion Sort for varying increments
void inssort2(Comparable* A[], int start, int incr, int n) {
  for (int i = start+incr; i < n; i += incr)
    for (int j = i; ((j >= incr) && (*A[j] < *A[j-incr])); j -= incr) 
      swap(A, j, j-incr);
}

30.18.1.3. Mergesort

30.18.1.4. Mergesort cost

  • Mergesort cost:
  • Mergsort is also good for sorting linked lists.
  • Mergesort requires twice the space.

30.18.1.5. Quicksort

void quicksort(Comparable[] A, int i, int j) { // Quicksort
  int pivotindex = findpivot(A, i, j);  // Pick a pivot
  swap(A, pivotindex, j);               // Stick pivot at end
  // k will be the first position in the right subarray
  int k = partition(A, i, j-1, A[j]);
  swap(A, k, j);                        // Put pivot in place
  if ((k-i) > 1) quicksort(A, i, k-1);  // Sort left partition
  if ((j-k) > 1) quicksort(A, k+1, j);  // Sort right partition
}
void quicksort(Comparable* A[], int i, int j) {
  int pivotindex = findpivot(i, j);
  swap(A, pivotindex, j); // Stick pivot at end
  // k will be the first position in the right subarray
  int k = partition(A, i, j-1,A[j]);
  swap(A, k, j);                       // Put pivot in place
  if ((k-i) > 1) quicksort(A, i, k-1); // Sort left partition
  if ((j-k) > 1) quicksort(A, k+1, j); // Sort right partition
}
int findpivot(Comparable[] A, int i, int j)
  { return (i+j)/2; }
int findpivot(int i, int j)
  { return (i+j)/2; }

30.18.1.6. Quicksort Partition

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.7. Quicksort Partition Cost

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.8. Quicksort Summary

30.18.1.9. Quicksort Worst Case

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.10. .

.

30.18.1.11. Quicksort Best Case

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.12. .

.

30.18.1.13. Quicksort Average Case

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.14. Optimizations for Quicksort

  • Better Pivot
  • Inline instead of function calls
  • Eliminate recursion
  • Better algorithm for small sublists: Insertion sort
    • Best: Don't sort small lists at all, do a final Insertion Sort to clean up.

30.18.1.15. Heapsort

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.16. Heapsort Analysis

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.17. Binsort

  for (i=0; i<A.length; i++)
    B[A[i]] = A[i];
  for (i=0; i<A.length; i++)
    B[A[i]] = A[i];
  for (i=0; i<A.length; i++)
    B[A[i]] = A[i];
  for (i=0; i<A.length; i++)
    B[A[i]] = A[i];
Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.18. Radix Sort: Linked List

30.18.1.19. .

.

30.18.1.20. Radix Sort: Array

30.18.1.21. Radix Sort Implementation

static void radix(Integer[] A, int k, int r) {
  Integer[] B = new Integer[A.length];
  int[] count = new int[r];     // Count[i] stores number of records with digit value i
  int i, j, rtok;

  for (i=0, rtok=1; i<k; i++, rtok*=r) { // For k digits
    for (j=0; j<r; j++) count[j] = 0;    // Initialize count

    // Count the number of records for each bin on this pass
    for (j=0; j<A.length; j++) count[(A[j]/rtok)%r]++;

    // count[j] will be index in B for last slot of bin j.
    // First, reduce count[0] because indexing starts at 0, not 1
    count[0] = count[0] - 1;
    for (j=1; j<r; j++) count[j] = count[j-1] + count[j];

    // Put records into bins, working from bottom of bin
    // Since bins fill from bottom, j counts downwards
    for (j=A.length-1; j>=0; j--) {
      B[count[(A[j]/rtok)%r]] = A[j];
      count[(A[j]/rtok)%r] = count[(A[j]/rtok)%r] - 1;
    }
    for (j=0; j<A.length; j++) A[j] = B[j]; // Copy B back
  }
}
static void radixsort(int A[], int k, int r, int n) {
  int B[n];
  int count[r];
  int i, j, rtok;
  
  for (i = 0, rtok = 1; i < k; i++, rtok *= r) {  // For k digits
    for (j = 0; j < r; j++) count[j] = 0;  // Initialize count
    
    // Count the number of records for each bin on this pass
    for (j = 0; j < n; j++) count[(A[j]/rtok)%r]++;
    
    // count[j] will be index in B for last slot of bin j.
    // First, reduce count[0] because indexing starts at 0, not 1
    count[0] = count[0] - 1;
    for (j = 1; j < r; j++) count[j] = count[j-1] + count[j];
    
    // Put records into bins, working from bottom of bin
    // Since bins fill from bottom, j counts downwards
    for (j  = n-1; j >= 0; j--) {
      B[count[(A[j]/rtok)%r]] = A[j];
      count[(A[j]/rtok)%r] = count[(A[j]/rtok)%r] - 1;
    }
    for (j = 0; j < n; j++) A[j] = B[j];  // Copy B back
  }
}

30.18.1.22. .

.

30.18.1.23. Radix Sort Analysis

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

30.18.1.24. Empirical Analysis

\[\begin{split}\begin{array}{l|rrrrrrrr} \hline \textbf{Sort} & \textbf{10}& \textbf{100} & \textbf{1K}& \textbf{10K} & \textbf{100K}& \textbf{1M}& \textbf{Up} & \textbf{Down}\\ \hline \textrm{Insertion} & .00023 & .007 & 0.66 & 64.98 & 7381.0 & 674420 & 0.04 & 129.05\\ \textrm{Bubble} & .00035 & .020 & 2.25 & 277.94 & 27691.0 & 2820680 & 70.64 & 108.69\\ \textrm{Selection} & .00039 & .012 & 0.69 & 72.47 & 7356.0 & 780000 & 69.76 & 69.58\\ \textrm{Shell} & .00034 & .008 & 0.14 & 1.99 & 30.2 & 554 & 0.44 & 0.79\\ \textrm{Shell/O} & .00034 & .008 & 0.12 & 1.91 & 29.0 & 530 & 0.36 & 0.64\\ \textrm{Merge} & .00050 & .010 & 0.12 & 1.61 & 19.3 & 219 & 0.83 & 0.79\\ \textrm{Merge/O} & .00024 & .007 & 0.10 & 1.31 & 17.2 & 197 & 0.47 & 0.66\\ \textrm{Quick} & .00048 & .008 & 0.11 & 1.37 & 15.7 & 162 & 0.37 & 0.40\\ \textrm{Quick/O} & .00031 & .006 & 0.09 & 1.14 & 13.6 & 143 & 0.32 & 0.36\\ \textrm{Heap} & .00050 & .011 & 0.16 & 2.08 & 26.7 & 391 & 1.57 & 1.56\\ \textrm{Heap/O} & .00033 & .007 & 0.11 & 1.61 & 20.8 & 334 & 1.01 & 1.04\\ \textrm{Radix/4} & .00838 & .081 & 0.79 & 7.99 & 79.9 & 808 & 7.97 & 7.97\\ \textrm{Radix/8} & .00799 & .044 & 0.40 & 3.99 & 40.0 & 404 & 4.00 & 3.99\\ \hline \end{array}\end{split}\]

30.18.1.25. Sorting Lower Bound (1)

  • We would like to know a lower bound for the problem of sorting
  • Sorting is \(O(n \log n)\) (average, worst cases) because we know of algorithms with this upper bound.
  • Sorting I/O takes \(\Omega(n)\) time. You have to look at all records to tell if the list is sorted.
  • We will now prove \(\Omega(n log n)\) lower bound for sorting.

30.18.1.26. Sorting Lower Bound (2)

   «  30.17. Sorting Part 1   ::   Contents   ::   30.19. File Processing and Buffer Pools  »

nsf
Close Window