Java中的快速排序实现,透视选择
我已经在java中的ArrayList上实现了一个通用的快速排序,但是它只有在我选择pivot作为数组中最右边的项时才起作用。我尝试选择中间项和随机项,这两个项都只返回部分排序的ArrayList。我特别想知道为什么quickSortRecursive中的两个注释掉的pivot选择方法会导致ArrayList无法完全排序。感谢您的帮助Java中的快速排序实现,透视选择,java,quicksort,Java,Quicksort,我已经在java中的ArrayList上实现了一个通用的快速排序,但是它只有在我选择pivot作为数组中最右边的项时才起作用。我尝试选择中间项和随机项,这两个项都只返回部分排序的ArrayList。我特别想知道为什么quickSortRecursive中的两个注释掉的pivot选择方法会导致ArrayList无法完全排序。感谢您的帮助 public static <T> void quicksort(ArrayList<T> a, Comparator<? supe
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);
}
publicstaticvoidquicksort(arraylista,Comparator)所以您几乎可以做到这一点,但是我可以看出这段代码有一些地方是错误的:
通常用于声明未知类型的函数或创建泛型函数,此处无需使用该函数。您只需使用您选择的任何类型的数组,即int[]data
,即可替代arrayList
- Pivot是在数据范围内任意选择的索引,尽管通常使用
(左+右)/2
它的类型很可能是int
- 您有两种方法
quickSortRecursive
和partition
。但是,这些方法属于一个函数,因为您需要为要排序的每个数据子集计算枢轴。此方法不需要返回类型,所以只需在方法声明中使用void
成功地将数据划分为子集后,需要选择一个轴,将该轴与该子集中的最后一项交换
然后,您需要循环遍历数据子集,并将每个数据项与枢轴值(我们刚刚交换它时,它位于数据子集的末尾)进行比较
交换物品
在交换所有项之后,有必要通过将数据与最后一个要排序的项交换,将枢轴索引中的数据放回原处
只有这样,才能对其余数据递归调用函数:
递归调用函数时:
quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
您应该将left而不是0传递到函数中,因为传递0将导致始终从数据最左侧排序
希望这能有所帮助。所以您就快到了,但是我发现这段代码有一些地方不对劲:
通常用于声明未知类型的函数或创建泛型函数,此处无需使用该函数。您只需使用您选择的任何类型的数组,即int[]data
,即可替代arrayList
- Pivot是在数据范围内任意选择的索引,尽管通常使用
(左+右)/2
它的类型很可能是int
- 您有两种方法
quickSortRecursive
和partition
。但是,这些方法属于一个函数,因为您需要为要排序的每个数据子集计算枢轴。此方法不需要返回类型,所以只需在方法声明中使用void
成功地将数据划分为子集后,需要选择一个轴,将该轴与该子集中的最后一项交换
然后,您需要循环遍历数据子集,并将每个数据项与枢轴值(我们刚刚交换它时,它位于数据子集的末尾)进行比较
交换物品
在交换所有项之后,有必要通过将数据与最后一个要排序的项交换,将枢轴索引中的数据放回原处
只有这样,才能对其余数据递归调用函数:
递归调用函数时:
quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
您应该将left而不是0传递到函数中,因为传递0将导致始终从数据最左侧排序
希望这能有所帮助。--rightCursor
首先递减变量,然后使用它(已经递减)
因此,由于right=a.size()-1;
最右边的元素将被忽略(轴元素除外,轴元素会被比较)。--rightCursor
首先递减变量,然后使用它(已经递减)
因此,由于right=a.size()-1;
最右边的元素将被忽略(轴元素除外,轴元素无论如何都会被比较).为什么不将选定元素与最右边的元素交换?随机性属性不取决于元素的数组最终位置。非常好的算法书籍就是这样进行的。您应该谈谈您自己为诊断问题所做的工作。为什么不将选定元素与最右边的元素交换?随机数mness属性不依赖于元素的数组最终位置。非常好的算法书籍就是这样进行的。您应该谈谈您自己为诊断问题所做的工作。