简体   繁体   English

Java中的快速排序问题

[英]Quicksort issue in Java

I am trying to implement quickSort using recursion and several methods to assist.我正在尝试使用递归和几种辅助方法来实现快速排序。 When I run the program I get an out of bounds message that tells me I have veered off into index -1 of the Array.当我运行程序时,我收到一条越界消息,告诉我我已经转向数组的索引 -1。 Can anyone offer advice about fixing my quickSort method?任何人都可以提供有关修复我的 quickSort 方法的建议吗? (this is where the problem lies). (这就是问题所在)。 I know my other methods are correct.我知道我的其他方法是正确的。

Example {7,6,5,4,3,2,1}示例 {7,6,5,4,3,2,1}

should come out to be {1,2,3,4,5,6,7}应该出来是 {1,2,3,4,5,6,7}

public static <T extends Comparable<? super T>> void quickSort(T[] a) {
        quickSort(a,0,a.length - 1);
    }

    public static <T extends Comparable<? super T>> void quickSort(T[] a,int start,int end) { 
        if(start<end) {
            int pivotIndex = partition(a, start, end);
            quickSort(a,start,pivotIndex-1); // sort left partition
            quickSort(a,pivotIndex+1,end); // sort right partition
        }

    }

    public static <T extends Comparable<? super T>> int partition(T[] a, int start, int end) {
        int mid =midpoint(start,end);
        sortFirstMiddleLast(a,start,mid,end);


        swap(a,mid,end-1);
        int pivotIndex = end -1 ;
        T pivotValue = a[pivotIndex];

        int indexFromLeft = start +1 ;
        int indexFromRight = end -2;
        boolean done = false;
        while (!done) {
            while (a[indexFromLeft].compareTo(pivotValue)<0) {
                indexFromLeft++;
                }
            while (a[indexFromRight].compareTo(pivotValue)>0) {
                indexFromRight--;
            }
            if (indexFromLeft < indexFromRight) {
                swap(a,indexFromLeft,indexFromRight);
                indexFromLeft++;
                indexFromRight--;
            }
            else {
                done=true;
            }

        }
            swap(a,pivotIndex,indexFromLeft);
            pivotIndex=indexFromLeft;

        return pivotIndex;
    }

    public static <T extends Comparable<? super T>> void sortFirstMiddleLast(T[] a, int start, int mid, int end) {
        if (a[start].compareTo(a[mid])>0) {
            swap(a,start,mid);
        }
        else if (a[mid].compareTo(a[end])>0) {
            swap(a,mid,end);
        }
        else if (a[start].compareTo(a[end])>0) {
            swap(a,start,end);
        }
        else if(a[start].compareTo(a[mid])>0) {
            swap (a,start,mid);
        }

        }

    private static int midpoint(int first, int last) {
            return first + (last - first) / 2;
        }

private static void swap(Object[] a, int first, int second) {
        Object temp = a[first];
        a[first] = a[second];
        a[second] = temp;
    }

The code is a variation of Hoare partition scheme.该代码是 Hoare 分区方案的变体。 Assuming you don't want add a range check to the inner loops, then the pivot element needs to be within the range between left and right indexes.假设您不想向内部循环添加范围检查,那么枢轴元素需要在左右索引之间的范围内。 The if after the two inner loops should use left index <= right index (not <).两个内部循环之后的 if 应该使用左索引 <= 右索引(而不是 <)。

Another issue is that with a typical Hoare partition scheme, the pivot or elements = pivot can end up anywhere, and the index returned by partition may not be the pivot.另一个问题是,在典型的 Hoare 分区方案中,pivot 或 elements = pivot 可以在任何地方结束,而 partition 返回的索引可能不是pivot。 The index just splits up the array into elements <= pivot and elements >= pivot (again elements == pivot or the pivot itself can end up anywhere).索引只是将数组拆分为元素 <= 枢轴和元素 >= 枢轴(同样,元素 == 枢轴或枢轴本身可以在任何地方结束)。 This means the calling code can't exclude the returned index from recursive calls.这意味着调用代码不能从递归调用中排除返回的索引。 Also for the typical Hoare partition scheme, the last element can't be used for a pivot, since that can result in infinite recursion.同样对于典型的 Hoare 分区方案,最后一个元素不能用于枢轴,因为这会导致无限递归。 Wiki article has an example of a pre-incrementing and pre-decrementing Hoare based quicksort. Wiki 文章有一个基于 Hoare 的预递增和预递减的快速排序示例。

https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme

Example C code for a post increment and decrement variation of Hoare partition scheme, with the partition logic merged into the quicksort function. Hoare 分区方案的后增量和减量变化的示例 C 代码,其中分区逻辑合并到快速排序功能中。 For this particular variation of Hoare partition scheme, any element, including the last element, can be used for the pivot, but choosing first or last element for pivot results in worst case time complexity of O(n^2) for already sorted or reverse sorted data, while choosing the middle element as shown below results in best case behavior for already sorted or reverse sorted data.对于 Hoare 分区方案的这种特殊变体,任何元素,包括最后一个元素,都可以用作主元,但是选择第一个或最后一个元素作为主元会导致最坏情况下 O(n^2) 的时间复杂度对于已经排序或反向排序数据,同时选择如下所示的中间元素会导致已排序或反向排序数据的最佳情况。

void QuickSort(int a[], int lo, int hi)
{
int i, j;
int p, t;
    if(lo >= hi)
        return;
    p = a[lo + (hi-lo)/2];
    i = lo;
    j = hi;
    while (i <= j){
        while (a[i] < p)i++;
        while (a[j] > p)j--;
            if (i > j)
                break;
            t = a[i];
            a[i] = a[j];
            a[j] = t;
            i++;
            j--;
    }
    QuickSort(a, lo, j);
    QuickSort(a, i, hi);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM