Quicksort排序不正确

时间:2019-05-29 21:34:11

标签: java sorting quicksort

我本质上是从UCBerkeley快速排序视频中复制代码的,但似乎几乎是成对排序的。我不确定这是怎么回事。

我已经多次浏览每行,看不到出了什么问题。一切对我来说都很有意义。

static <E extends Comparable<? super E>>
void quicksort(E[] A, int low, int high) {
    if (low < high) {
        int pivotIndex = (low + high) / 2;
        E pivot = A[pivotIndex];
        // move pivot to end
        A[pivotIndex] = A[high];
        A[high] = pivot;

        int i = low - 1;
        int j = high;
        do {
            do {
                i++;
            } while (A[i].compareTo(pivot) < 0);
            do {
                j--;
            } while ((A[i].compareTo(pivot)) > 0 && (j > low));
            if (i < j) {
                E swap = A[i];
                A[i] = A[j];
                A[j] = swap;
            }
        } while (i < j);
        // i is now the first spot in the right partition (where we will put pivot)
        // now put pivot back where it belongs
        A[high] = A[i];
        A[i] = pivot;
        quicksort(A, low, i - 1); // sort left partition
        quicksort(A, i + 1, high);
    }
}

我期望[2、3、5、6、10、101、200、300],但得到了[3、5、2、6、10、101、200、300]

1 个答案:

答案 0 :(得分:1)

当第二个内部循环中的比较应该使用A [j]时,则使用A [i]:

            } while ((A[j].compareTo(pivot)) > 0 && (j > low));  // A[j] not A[i]

这种类型的快速排序的另一种变体是不将枢轴与A [high]交换,并且通过将枢轴保留在中间,代码无需在第二个内部循环中检查j> low,这有点快。使用此变体还需要进行其他更改:将j初始化为high + 1,并且两个递归调用应为quicksort(A,low,j)和quicksort(A,j + 1,high)。请注意,等于枢轴的值(包括枢轴本身)可能会在任一分区中终止,因为等于枢轴的值会被交换。

基元(int)的示例代码,该代码在较小或相等的部分上使用递归,然后对较大的部分进行迭代,以避免在最坏的情况下发生堆栈溢出。可以将其转换为使用通用对象E。

    public static void qsort(int[] a, int lo, int hi)
    {
        while(lo < hi){
            int  md = lo+(hi-lo)/2;
            int  ll = lo-1;
            int  hh = hi+1;
            int p = a[md];
            int t;
            while(true){
                while(a[++ll] < p);
                while(a[--hh] > p);
                if(ll >= hh)
                    break;
                t     = a[ll];
                a[ll] = a[hh];
                a[hh] = t;
            }
            ll = hh++;
            if((ll - lo) <= (hi - hh)){
                qsort(a, lo, ll);
                lo = hh;
            } else {
                qsort(a, hh, hi);
                hi = ll;
            }
        }
    }