0

我编写了以下代码以进行快速排序,并且对于唯一数字似乎做得很好。
但是,当存在重复项时,它会惨遭失败。
帮助进行重复调整表示赞赏:

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);

            }



            }
4

3 回答 3

0

while(right > 0 && data[--right]>pivotval);

你需要扭转这个测试,否则你永远无法到达任何地方。

于 2013-07-13T03:19:31.903 回答
0

您将枢轴移动到最右边,但是当您想在 while 循环之后交换回枢轴时,您调用swap(left,_right,data);,但left 不等于 pivotpivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2;但 left 是不确定的。看起来您想使用 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;
    }
于 2013-08-11T06:22:37.610 回答
0

您应该决定如何处理相等的元素。最简单的解决方案是将它们扔到一边说右边:

        while(true){

            while(right > 0 &&  data[--right]>=pivotval);
            while(data[++left]<pivotval);
            if(right<=left) break;
            swap(left,right,data);

        }

这里的问题是算法在某些情况下会非常慢。更好的方法是形成第三个相等元素的区域,该区域从枢轴开始在数组的中心增长。

一种更简单、更容易的方法进行两次迭代——第一次你过滤大于枢轴的元素以在数组的右端形成一个组,第二次你在左端形成一组较小的元素。介于两者之间的任何东西都等于枢轴。

希望这可以帮助。

于 2013-07-12T14:48:24.563 回答