快速排序java

來源:互聯網
上載者:User
設要排序的數組是A[0]……A[N-1],首先任意選取一個資料(通常選用數組的第一個數)作為關鍵資料,
然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。
然後對關鍵字前面和後面的部分分別再進行上面的步驟。
一趟快速排序的演算法是:
1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;
2)以第一個數組元素作為關鍵資料,賦值給key,即key=A[0];
3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;
4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;
5)重複第3、4步,直到i=j; (3,4步中,沒找到合格值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,
使得j=j-1,i=i+1,直至找到為止。找到合格值,進行交換的時候i, j指標位置不變。
另外,i==j這一過程一定正好是i+或j-完成的時候,此時令迴圈結束)。
下面是選取第一個元素用作樞紐元素的快速排序實現:
public static void quickSort(int[] datas, int low, int high) {if(low < high){int privot = getPrivot(datas, low, high);quickSort(datas, low, privot - 1);quickSort(datas, privot + 1, high);}}private static int getPrivot(int[] datas, int low, int high) {int temp = datas[low];while (low < high) {while (low < high && datas[high] > temp) {high--;}datas[low] = datas[high];while (low < high && datas[low] < temp) {low++;}datas[high] = datas[low];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               }datas[low] = temp;return low;}


時間複雜度:
最壞情況:樞紐元素始終是最小元素,O(n^2)
  public  static  void quickSort( int[] datas,  int low,  int high) {  //T(N)
     if (low < high){  
         int privot = getPrivot(datas, low, high);  // cN  此處兩邊分別 low , hight 分 別向中間移動,移動的總次數為 N
        quickSort(datas, low, privot -  1 ); // T(i)
       quickSort(datas, privot +  1, high);  //T(N-i-1)
    }  
}  
---> T(N) = T(i) + T(N-i-1) + cN
令 i = 0 ,
 ---> T(N) = T(N-1) + cN + 1  (T(0) = 1 )
忽略 T(0) = 1,
--->
T(N) = T(N-1) + cN
T(N-1) = T(N-2) + c(N-1)
T(N-2) = T(N-3) + c(N-2)
....
T(2) = T(1) + c ( 2 )
兩邊相加
--->
T(N) = T(1) +  = O(N^2)
最好情況:樞紐元素正好位於正中間,O(n log n)
假設兩個子數組剛好為原數組的一半
則:
T(N) = T(i) + T(N-i-1) + cN
T(N) = T(N/2) + T(N/2) + cN = 2 T(N/2) + cN
--->
T(N)/N = = 2 T(N/2)?N + c
...
--->
T(N)/N = T(1)/1 + c logN
T(N) = cNlogN + N = O(NlogN)
 平均情況:O(n log n)
樞紐元素的選擇:
通常可能會選擇第一個元素作為樞紐元素,如果是輸入時隨機的,那麼這麼做是可以的,但是如果輸入是預順序的或者反序的,那麼這樣的樞紐就會產生一個比較劣質的
分割。如果第一個元素用作樞紐元素而且輸入於排序的,那麼快速排序花費的時間是二次的。預排序的輸入或者有一段排序的輸入是很常見的。所以選擇第一個做樞紐元不是很可取的辦法。
一種安全的方案是隨機選取樞紐元。隨機的樞紐元(隨機數發生器)不可能總是連續不斷的產生劣質的樞紐元,但是隨機數的產生一般開銷很大,根本不能減少演算法其餘部分的平均已耗用時間。

三數中值分割法:樞紐元最好的選擇是選擇數組的中位元。但是,這很難算出並且會明顯減慢快速排序的速度。這樣的中值估算值可以通過隨機選取三個元素並且用他們的中位元得到。一般可以選擇左端、右端、中心位置上的三個元素的中位元作為樞紐元。




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.