Java中的快速排序问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的快速排序问题相关的知识,希望对你有一定的参考价值。
我正在尝试使用递归和多种方法来实现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;
}
答案
该代码是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);
}
以上是关于Java中的快速排序问题的主要内容,如果未能解决你的问题,请参考以下文章