我在java中的ArrayList上实现了一个通用的quickSort,但只有当我选择pivot作为数组中最右边的项时它才有效。我已经尝试选择中间项和随机项,这两个都返回ArrayList仅部分排序。我特别想知道为什么两个注释掉quickSortRecursive中的透视选择方法导致ArrayList不能一直排序。任何帮助表示赞赏!
public static <T> void quicksort(ArrayList<T> a, Comparator<? super T> cmp){
int left = 0;
int right = a.size()-1;
quickSortRecursive(left, right,a, cmp);
}
private static <T> void quickSortRecursive(int left,int right, ArrayList<T> a, Comparator<? super T> cmp){
if(left >= right){
return;
}
T pivot = a.get(right);
//T pivot = a.get(rand.nextInt(a.size()-1));
//T pivot = a.get((left+right)/2);
int partition = partition(left, right, pivot, a, cmp);
quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
}
private static <T> int partition(int left,int right,T pivot, ArrayList <T> a,Comparator<? super T> cmp){
int leftCursor = left-1;
int rightCursor = right;
while(leftCursor < rightCursor){
while(cmp.compare(a.get(++leftCursor), pivot)<0);
while(rightCursor > 0 && (cmp.compare(a.get(--rightCursor), pivot)>0));
if(leftCursor >= rightCursor){
break;
}
else{
swap(leftCursor, rightCursor, a);
}
}
swap(leftCursor, right, a);
return leftCursor;
}
public static <T> void swap(int left,int right, ArrayList<T> a){
T temp = a.get(left);
a.set(left, a.get(right));
a.set(right, temp);
}
答案 0 :(得分:0)
所以你几乎到了那里但是有些事情我看错了这段代码:
<T>
通常用于声明具有未知类型的函数或创建通用函数,此处不必使用它。您可以简单地使用您选择的任何类型的数组,即int[] data
。(left + right) / 2
它常见的类型很可能是int
。quickSortRecursive
和partition
。但是,这些属于一个函数,因为您需要为要排序的数据的每个子集计算轴。此方法不需要返回类型,因此只需在方法声明中使用void
。成功将数据划分为子集后,您需要选择一个数据透视表,将该数据透视与该子集中的最后一项交换。
然后,您需要遍历数据子集并将每个数据项与数据透视值进行比较(数据子集位于数据子集的末尾,因为我们刚刚交换它)。如果数据项小于pivot索引处的值,则 交换物品。
在交换了所有项目之后,有必要将数据放在枢轴索引处,将其与最后一个要排序的项目交换。
只有才能递归调用其余数据上的函数:
递归调用函数时:
quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
你应该向左传递而不是0进入函数,因为传递0将导致总是从数据的最左侧进行排序。
希望这有帮助。
答案 1 :(得分:0)
--rightCursor
首先递减变量然后使用它(已经递减)。
所以,自right=a.size()-1;
以来,最右边的元素将被忽略(除了最后比较的枢轴元素)。