Java中的快速排序问题

问题描述 投票:1回答:1

我正在尝试使用递归和多种方法来实现quickSort。当我运行程序时,我收到一条越界消息,告诉我我已经转向Array的索引-1。谁能提供有关修复我的quickSort方法的建议? (这就是问题所在)。我知道我的其他方法是正确的。

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

应该是{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;
    }
java quicksort
1个回答
0
投票

该代码是Hoare分区方案的变体。假设您不想在内部循环中添加范围检查,则数据透视元素需要在左右索引之间的范围内。在两个内部循环之后的if应该使用左索引<=右索引(不是

另一个问题是,在典型的Hoare分区方案中,数据透视表或元素=数据透视表可以终止于任何位置,并且分区返回的索引可能不是该数据透视表。索引只是将数组拆分为元素<=枢轴和元素> =枢轴(同样,元素==枢轴或枢轴本身可以终止于任何地方)。这意味着调用代码无法从递归调用中排除返回的索引。同样对于典型的Hoare分区方案,最后一个元素也不能用于数据透视,因为这可能导致无限递归。 Wiki文章提供了一个基于Hoare的预先递增和递减的快速排序示例。

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

用于Hoare分区方案的后递增和递减变化的示例C代码,其中分区逻辑已合并到quicksort函数中:

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.