Quicksort重复

时间:2013-07-12 14:11:04

标签: java algorithm quicksort

我编写了以下代码用于快速排序,它似乎对唯一数字做得很好 但是,当存在重复时,它会失败 在重复调整时,我们非常感谢您的帮助:

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

            }



            }

3 个答案:

答案 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;