简体   繁体   English

快速排序重复项

[英]Quicksort for duplicates

I composed the following code for quick sort,and it seems to be doing fine for unique numbers. 我编写了以下代码以进行快速排序,对于唯一数字来说似乎做得很好。
However,it fails miserably when duplicates are present. 但是,当存在重复项时,它会失败。
Help is appreciated in making the adjustment 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);

            }



            }

You should decide what you do with the equal elements. 您应该决定如何使用相等的元素。 The simplest solution is to throw them on one side say to the right: 最简单的解决方案是将它们放在右侧说的一侧:

        while(true){

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

        }

Problem here is that the algorithm will be really slow on some cases. 这里的问题是该算法在某些情况下会非常慢。 Better approach is to form a third region of equal elements that grows in the center of the array from the pivot onwards. 更好的方法是形成相等元素的第三个区域,该区域从枢轴开始在数组的中心增长。

A simpler and easier approach does two iterations - on first one you filter elements bigger than the pivot to form a group at the right end of the array, on second you form a group of smaller elements at the left end. 一种更简单易用的方法进行了两次迭代-第一个迭代是过滤比枢轴大的元素以在数组的右端形成一组,第二个则在左端形成一组较小的元素。 Anything in between is equal to the pivot. 两者之间的任何事物都等于枢轴。

Hope this helps. 希望这可以帮助。

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

You need to reverse this test, otherwise you never get anywhere. 您需要撤销此测试,否则您将无处可寻。

You move the pivot to the extreme right, but when you want to swap back the pivot after the while loop, you call swap(left,_right,data); 您将枢轴移到最右端,但是当您希望在while循环后换回枢轴时,可以调用swap(left,_right,data); , but left is not equal to pivot , pivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2; ,但left不等于ivotpivot=(left+right)%2==0?(left+right)/2:(left+right+1)/2; , but left is uncertain. ,但不确定。 It looks like you want to use Hoare-Partition. 看来您想使用Hoare-Partition。 Here it is: 这里是:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM