簡體   English   中英

快速排序重復項

[英]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不等於ivotpivot=(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM