程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java編程中疾速排序算法的完成及相干算法優化

Java編程中疾速排序算法的完成及相干算法優化

編輯:關於JAVA

Java編程中疾速排序算法的完成及相干算法優化。本站提示廣大學習愛好者:(Java編程中疾速排序算法的完成及相干算法優化)文章只能為提供參考,不一定能成為您想要的結果。以下是Java編程中疾速排序算法的完成及相干算法優化正文


時光龐雜度

均勻情形:O(nlgn)
最壞情形:O(n*n),產生在當數據曾經是排序狀況時
快排算法的根本道理

1、從數據當選取一個值a[i]作為參考
2、以a[i] 為參考,將數據分紅2部門:P1、P2,P1中的數據全體≤a[i],P2中的數據全體>a[i],數據變成{{P1}{a[i]}{P2}}
3、將P1、P2反復上述步調,直到各部門中只剩1個數據
4、數據完成升序分列

根本示例:

原始數據:

  {3,9,8,5,2,1,6}

第1步:拔取第1個數據:3
第2步:將數據分紅2部門,右邊≤3,左邊年夜於>3:

  {2,1} {3} {9,8,5,6}

第3步:將各部門反復以上步調,直到每部門只剩1個數據:

  {2,1} => {1} {2}
  {9,8,5,6} => {8,5,6} {9}=> {5,6} {8} {9}=> {5} {6} {8} {9}

第4步:數據完成升序分列:

  {1} {2} {3} {5} {6} {8} {9}

法式中數據平日保留在數組中,以int類型的數組為例,可以將下面的步調寫成一個quickSort函數原型:

quickSort(int begin, int end) { 
//begin為數組的第一個數據的索引值,end為數組的最初一個數據的索引值+1
  //假如只要1個數據或0個數據,則法式前往
  if( begin == end || begin == (end-1) ) return; 
  int p = in[begin];//p為選擇的參考數據,選擇第一個數據
  int a = begin +1; //a作為2部門數據分界限的索引值
  int b = a;//b為待比擬的數據的索引值
  for( ; b < end; b++) {//將數組中的各個數據順次與參考數據停止比擬
    if( in[b] < p) { //假如該數據<參考數據則將其挪動到右邊
      if(a == b){a++; continue;} //假如該數據曾經在右邊則不動
      int temp = in[a];//將數據挪動到右邊
      in[a] = in[b];
      in[b] = temp;
      a++;//將分界限右移
    }
  }
  in[begin] = in[a-1];//講參考值挪動到2組數據中央
  in[a-1] = p;
  if( a-1 > begin){ // 假如右邊稀有據則將其反復上述步調
    quickSort(begin, a);
  } 
  if( end-1 > a ) {// 假如左邊稀有據則將其反復上述步調
    quickSort(a, end);
  } 
  return; // 假如有數據前往
}

算法優化
下面這個疾速排序算法可以說是最根本的疾速排序,由於它並沒有斟酌任何輸出數據。然則,我們很輕易發明這個算法的缺點:這就是在我們輸出數據根本有序乃至完整有序的時刻,這算法退步為冒泡排序,不再是O(n㏒n),而是O(n^2)了。
究其本源,在於我們的代碼完成中,每次只從數組第一個開端取。假如我們采取“三者取中”,即arr[low],arr[high],arr[(low+high)/2]三者的中值作為樞軸記載,則可以年夜年夜進步疾速排序在最壞情形下的機能。然則,我們依然沒法將它在數組有序情況下的機能進步到O(n)。還有一些辦法可以分歧水平地進步疾速排序在最壞情形下的時光機能。

另外,疾速排序須要一個遞歸棧,平日情形下這個棧不會很深,為log(n)級別。然則,假如每次劃分的兩個數組長度嚴重掉衡,則為最壞情形,棧的深度將增長到O(n)。此時,由棧空間帶來的空間龐雜度弗成疏忽。假如加上額定變量的開支,這裡乃至能夠到達恐懼的O(n^2)空間龐雜度。所以,疾速排序的最差空間龐雜度不是一個定值,乃至能夠不在一個級別。
為懂得決這個成績,我們可以在每次劃分後比擬兩頭的長度,並先對短的序列停止排序(目標是先停止這些棧以釋放空間),可以將最年夜深度降回到O(㏒n)級別。

這裡提出對疾速排序的3點優化思緒:
關於小數組,可以采取拔出排序,防止遞歸挪用。例如,當if(hi <= lo + M)時,便可以轉到拔出排序。
采取子數組的一部門元素的中位數來切分數組。如許做獲得的切分更好,但價值是須要盤算中位數。
假如數組中含有年夜量的反復元素,可以采取三向切分。將數組切分為三部門,分離對應於小於、等於和年夜於切分元素的數組元素。代碼完成以下:

  private static void sort1(int[] a, int lo, int hi) {
  if (hi <= lo)
    return;
  int lt = lo, i = lo + 1, gt = hi;
  int v = a[lo];
  while (i <= gt) {
    if (a[i] < v) {
      swap(a, lt++, i++);
    } else if (a[i] > v) {
      swap(a, i, gt--);
    } else {
      i++;
    }
    sort(a, lo, lt - 1);
    sort(a, gt + 1, hi);
  }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved