[英]Quicksort for duplicates
我编写了以下代码以进行快速排序,对于唯一数字来说似乎做得很好。
但是,当存在重复项时,它会失败。
感谢您对重复项进行调整:
class QuickSort{
public static void sort(int left,int right,int[] data){
if(right-left <= 0) return;
int pivot=organize(left,right,data);
sort(left,pivot-1,data);
sort(pivot,right,data);
}
private static int organize(int left,int right,int[] data){
int _right=right;
int _left=left;
int pivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2;
//Move the pivot to the extreme right.
int pivotval=data[pivot];
swap(pivot,right,data);
left=left-1;//to adjust teh stating pointer
while(true){
while(right > 0 && data[--right]>pivotval);
while(data[++left]<pivotval);
if(right<=left) break;
swap(left,right,data);
}
swap(left,_right,data);
return left;
}
private static void swap(int left,int right,int[] data){
int temp=data[right];
data[right]=data[left];
data[left]=temp;
}
public static void main(String[] args){
int N=Integer.parseInt(args[0]);
int[] data=new int[N];
Random r=new Random();
for(int i=0 ;i<N;i++)
data[i]=r.nextInt(N);
//After populating the array
QuickSort.sort(0,data.length-1,data);
}
}
您应该决定如何使用相等的元素。 最简单的解决方案是将它们放在右侧说的一侧:
while(true){
while(right > 0 && data[--right]>=pivotval);
while(data[++left]<pivotval);
if(right<=left) break;
swap(left,right,data);
}
这里的问题是该算法在某些情况下会非常慢。 更好的方法是形成相等元素的第三个区域,该区域从枢轴开始在数组的中心增长。
一种更简单易用的方法进行了两次迭代-第一个迭代是过滤比枢轴大的元素以在数组的右端形成一组,第二个则在左端形成一组较小的元素。 两者之间的任何事物都等于枢轴。
希望这可以帮助。
while(right> 0 && data [-right]> pivotval);
您需要撤销此测试,否则您将无处可寻。
您将枢轴移到最右端,但是当您希望在while循环后换回枢轴时,可以调用swap(left,_right,data);
,但left不等于ivot , pivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2;
,但不确定。 看来您想使用Hoare-Partition。 这里是:
private static int organize(int left,int right,int[] data){
int pivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2;
//Move the pivot to the extreme right.
int pivotval=data[pivot];
//swap(pivot,right,data);
left=left-1;//to adjust the stating pointer
right = right + 1;
while(true){
while(right > 0 && data[--right]>pivotval);
while(data[++left]<pivotval);
if(right<=left) break;
swap(left,right,data);
}
//swap(left,right,data);
return left;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.