Random Pivot QuickSort无法正确排序

时间:2017-12-01 18:30:59

标签: java sorting random quicksort

从output.txt快照中可以看到。常规数据透视快速排序正常工作,但是当生成随机数据透视索引时,它不再正常工作。任何想法为什么?当调用quicksort方法时,如果我们想要选择随机数据条索引,则rand值为true,否则如果我们要选择最后一个 - 1作为数据透视索引,则为rand值。

// QUICK SORT
public static <T extends Comparable<? super T>>
       void quickSort(T[] array, int n, int basecase, boolean rand)
{
    quickSort(array, 0, n-1, basecase, rand);
} // end quickSort

/** Sorts an array into ascending order. Uses quick sort with
 *  median-of-three pivot selection for arrays of at least 
 *  MIN_SIZE elements, and uses insertion sort for other arrays. */
public static <T extends Comparable<? super T>>
       void quickSort(T[] a, int first, int last, int basecase, boolean rand)
{
  if (last - first + 1 < basecase)
  {
    insertionSort(a, first, last);
  }
  else
  {
    // create the partition: Smaller | Pivot | Larger
    int pivotIndex = partition(a, first, last, rand);

    // sort subarrays Smaller and Larger
    quickSort(a, first, pivotIndex - 1, basecase, rand);
    quickSort(a, pivotIndex + 1, last, basecase, rand);
  } // end if
} // end quickSort

// 12.17
/** Task: Partitions an array as part of quick sort into two subarrays
 *        called Smaller and Larger that are separated by a single
 *        element called the pivot. 
 *        Elements in Smaller are <= pivot and appear before the 
 *        pivot in the array.
 *        Elements in Larger are >= pivot and appear after the 
 *        pivot in the array.
 *  @param a      an array of Comparable objects
 *  @param first  the integer index of the first array element; 
 *                first >= 0 and < a.length 
 *  @param last   the integer index of the last array element; 
 *                last - first >= 3; last < a.length
 *  @return the index of the pivot */
private static <T extends Comparable<? super T>>
        int partition(T[] a, int first, int last, boolean rand)
{
  int mid = (first + last)/2;
  sortFirstMiddleLast(a, first, mid, last);

  // Assertion: The pivot is a[mid]; a[first] <= pivot and 
  // a[last] >= pivot, so do not compare these two array elements
  // with pivot.

  // move pivot to next-to-last position in array
  swap(a, mid, last - 1);

  Random r = new Random();
  int pivotIndex = (rand) ? (first + r.nextInt(last - first + 1)) : (last - 1);
  T pivot = a[pivotIndex];

  // determine subarrays Smaller = a[first..endSmaller]
  // and                 Larger  = a[endSmaller+1..last-1]
  // such that elements in Smaller are <= pivot and 
  // elements in Larger are >= pivot; initially, these subarrays are empty

  int indexFromLeft = first + 1; 
  int indexFromRight = last - 2; 
  boolean done = false;
  while (!done)
  {
    // starting at beginning of array, leave elements that are < pivot;
    // locate first element that is >= pivot; you will find one,
    // since last element is >= pivot
    while (a[indexFromLeft].compareTo(pivot) < 0)
      indexFromLeft++;

    // starting at end of array, leave elements that are > pivot; 
    // locate first element that is <= pivot; you will find one, 
    // since first element is <= pivot
    while (a[indexFromRight].compareTo(pivot) > 0)
      indexFromRight--;

    assert a[indexFromLeft].compareTo(pivot) >= 0 && 
           a[indexFromRight].compareTo(pivot) <= 0;

    if (indexFromLeft < indexFromRight)
    {
      swap(a, indexFromLeft, indexFromRight);
      indexFromLeft++;
      indexFromRight--;
    }
    else 
      done = true;
  } // end while

  // place pivot between Smaller and Larger subarrays
  swap(a, pivotIndex, indexFromLeft);
  pivotIndex = indexFromLeft;

  // Assertion:
  //   Smaller = a[first..pivotIndex-1]
  //   Pivot = a[pivotIndex]
  //   Larger = a[pivotIndex+1..last]

  return pivotIndex; 
} // end partition

输出

output.txt

0 个答案:

没有答案