1. 程式人生 > >資料結構-排序-快速排序之三分取中法

資料結構-排序-快速排序之三分取中法

思想:引入的原因:雖然隨機選取樞軸時,減少出現不好分割的機率,但是還是最壞情況下還是O(n^2),要緩解這種情況,就引入了三數取中選取樞軸

分析:最佳的劃分是將待排序的序列分成等長的子序列,最佳的狀態我們可以使用序列的中間的值,也就是第N/2個數。可是,這很難算出來,並且會明顯減慢快速排序的速度。這樣的中值的估計可以通過隨機選取三個元素並用它們的中值作為樞紐元而得到。事實上,隨機性並沒有多大的幫助,因此一般的做法是使用左端、右端和中心位置上的三個元素的中值作為樞紐元。顯然使用三數中值分割法消除了預排序輸入的不好情形,並且減少快排大約14%的比較次數

舉例:待排序序列為:8 1 4 9 6 3 5 2 7 0

左邊為:8,右邊為0,中間為6.

我們這裡取三個數排序後,中間那個數作為樞軸,則樞軸為6

注意:在選取中軸值時,可以從由左中右三個中選取擴大到五個元素中或者更多元素中選取,一般的,會有(2t+1)平均分割槽法(median-of-(2t+1),三平均分割槽法英文為median-of-three)。

具體思想:對待排序序列中low、mid、high三個位置上資料進行排序,取他們中間的那個資料作為樞軸,並用0下標元素儲存樞軸。

即:採用三數取中,並用0下標元素儲存樞軸。

程式碼實現:

class Test{
    /*
       * @Description :  一趟快速排序
       * @param array
      * @param low
      * @param high
       * @return :   int
       * @exception :
       * @date :   2019/1/9 11:22
       */
     public static int partion(int [] array,int low,int high){

         int tmp=array[low];
         while(low<high){
             while(low<high && array[high]>tmp){
                 high--;
             }
             if(low>=high){
                 break;
             }else{
                 array[low]=array[high];
             }
             while(low<high&&array[low]<tmp){
                 low++;
             }
             if(low>=high){
                 break;
             }else{
                 array[high]=array[low];
             }
         }
         array[low]=tmp;
         return low;
     }
     public static void swap(int []array ,int low,int rand){
         int tmp=array[low];
         array[low]=array[rand];
         array[rand]=tmp;
     }
     public static void midThree(int [] array,int low,int high){
         //array[mid]<=array[low]<=array[high];  //實現原理
         int mid =(low+high)>>1;
         if(array[low]<array[mid]){
             swap(array,low,mid);
         }
         if(array[low]>array[high]){
             swap(array,low,high);
         }
         if(array[mid]>array[high]){
             swap(array,mid,high);
         }
     }
     public static void quick(int [] array,int low,int high){
             midThree(array,low,high);
             int par=partion(array,low,high);
         if(par > low+1) {
             quick(array,low,par-1);
         }
         if(par < high-1) {
             quick(array,par+1,high);
         }
     }
     public static void quickSort(int [] array){
         quick(array,0,array.length-1);
     }
     public static void main(String [] args){
         int array []=new int[10000];
         Random random=new Random();
         for(int i=0;i<array.length;i++){
             array[i]=random.nextInt(10000)+1;
         }
         quickSort(array);
     }
    }