我编写了以下代码用于快速排序,它似乎对唯一数字做得很好 但是,当存在重复时,它会失败 在重复调整时,我们非常感谢您的帮助:
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);
}
}
答案 0 :(得分:0)
你应该决定用相同的元素做什么。最简单的解决方案是将它们放在一边说右边:
while(true){
while(right > 0 && data[--right]>=pivotval);
while(data[++left]<pivotval);
if(right<=left) break;
swap(left,right,data);
}
这里的问题是在某些情况下算法会非常慢。更好的方法是形成一个相等元素的第三个区域,该区域从枢轴向上生长在阵列的中心。
一种更简单,更简单的方法可以进行两次迭代 - 第一种方法是过滤大于枢轴的元素,在数组的右端形成一个组,第二种方法是在左端形成一组较小的元素。介于两者之间的任何东西都等于枢轴。
希望这有帮助。
答案 1 :(得分:0)
while(右> 0&amp;&amp; data [ - right]&gt; pivotval);
你需要反转这个测试,否则你永远无法到达任何地方。
答案 2 :(得分:0)
您将枢轴移动到最右侧,但是当您想在while循环后交换枢轴时,您调用swap(left,_right,data);
,但左侧不等于枢轴,{ {1}},但左边是不确定的。
看起来你想要使用Hoare-Partition。这是:
pivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2;