php常用的四種排序演算法

gb4215287發表於2017-09-30

純當練習,高手請繞過。以一維陣列為例。

1.插入排序

思想:

每次將一個待排序的資料元素插入到前面已經排好序的數列中,使數列依然有序,知道待排序資料元素全部插入完為止。

示例:

[初始關鍵字] [49] 38 65 97 76 13 27 49
J=2(38) [38 49] 65 97 76 13 27 49
J=3(65) [38 49 65] 97 76 13 27 49
J=4(97) [38 49 65 97] 76 13 27 49
J=5(76) [38 49 65 76 97] 13 27 49
J=6(13) [13 38 49 65 76 97] 27 49
J=7(27) [13 27 38 49 65 76 97] 49
J=8(49) [13 27 38 49 49 65 76 97]

時間複雜度:

如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數加上(n-1)次。平均來說插入排序演算法的時間複雜度為O(n^2)。因而,插入排序不適合對於資料量比較大的排序應用。但是,如果需要排序的資料量很小,例如,量級小於千,那麼插入排序還是一個不錯的選擇。

程式碼:


  1. </pre><pre name="code" class="php">function insert_sort($arr){     
  2.     $count = count($arr);     
  3.     for($i=1; $i<$count$i++){     
  4.         $tmp = $arr[$i];     
  5.         $j = $i - 1;     
  6.         while($arr[$j] > $tmp){     
  7.             $arr[$j+1] = $arr[$j];     
  8.             $arr[$j] = $tmp;     
  9.             $j--;     
  10.          }     
  11.      }     
  12.     return $arr;     
  13. }    

2.選擇排序

思想:每一趟從待排序的資料元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到全部待排序的資料元素排完。

示例:

[初始關鍵字] [49 38 65 97 76 13 27 49]
第一趟排序後 13 [38 65 97 76 49 27 49]
第二趟排序後 13 27 [65 97 76 49 38 49]
第三趟排序後 13 27 38 [97 76 49 65 49]
第四趟排序後 13 27 38 49 [49 97 65 76]
第五趟排序後 13 27 38 49 49 [97 97 76]
第六趟排序後 13 27 38 49 49 76 [76 97]
第七趟排序後 13 27 38 49 49 76 76 [ 97]
最後排序結果 13 27 38 49 49 76 76 97

時間複雜度:

時間複雜度為o(n2),不穩定排序,適合規模比較小的

程式碼

  1. function selectsort($arr){  
  2. $num = count($arr);  
  3. for ($i=0; $i < $num-1; $i++) {  
  4. //先假設最小位置  
  5. $p = $i;  
  6. for ($k=$i+1; $k<$num$k++) {  
  7. //最小值跟當前值的比較  
  8. if($arr[$p]>$arr[$k]){  
  9. $p = $k;  
  10. }  
  11. }  
  12. //如果最小值不是當前位置,把最小值放到當前位置  
  13. if($p!=$i){  
  14. $tmp = $arr[$p];  
  15. $arr[$p] = $arr[$i];  
  16. $arr[$i] = $tmp;  
  17. }  
  18. }  
  19. return $arr;  
  20. }  


3.氣泡排序

思想:

兩兩比較待排序資料元素的大小,發現兩個資料元素的次序相反時即進行交換,直到沒有反序的資料元素為止。

示例:

 

49 13 13 13 13 13 13 13
38 49 27 27 27 27 27 27
65 38 49 38 38 38 38 38
97 65 38 49 49 49 49 49
76 97 65 49 49 49 49 49
13 76 97 65 65 65 65 65
27 27 76 97 76 76 76 76
49 49 49 76 97 97 97 97

時間複雜度:

該演算法的時間複雜度為O(n2)。但是,當原始關鍵字序列已有序時,只進行一趟比較就結束,此時時間複雜度為O(n)

程式碼

  1. //氣泡排序(一維陣列)     
  2. function bubble_sort($array){     
  3.     $count = count($array);     
  4.     if ($count <= 0) return false;     
  5.     for($i=0; $i<$count$i++){     
  6.         for($j=$count-1; $j>$i$j--){     
  7.             if ($array[$j] < $array[$j-1]){     
  8.                 $tmp = $array[$j];     
  9.                 $array[$j] = $array[$j-1];     
  10.                 $array[$j-1] = $tmp;     
  11.              }     
  12.          }     
  13.      }     
  14.     return $array;     
  15. }   


4.快速排序

思想:

通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。

示例:

 

初始關鍵字 [49 38 65 97 76 13 27 49]
一趟排序之後 [27 38 13] 49 [76 97 65 49]
二趟排序之後 [13] 27 [38] 49 [49 65]76 [97]
三趟排序之後 13 27 38 49 49 [65]76 97
最後的排序結果 13 27 38 49 49 65 76 97

時間複雜度:

快速排序主體演算法時間運算量約 O(log2n),劃分子區函式運算量約 O(n),所以總的時間複雜度為 O(nlog2n),它顯然優於氣泡排序 O(n2).可是演算法的優勢並不是絕對的。試分析,當原檔案關鍵字有序時,快速排序時間複雜度是 O(n2),這種情況下快速排序不快。而這種情況的氣泡排序是 O(n),反而很快。在原檔案記錄關鍵字無序時的多種排序方法中,快速排序被認為是最好的一種排序方法。

程式碼:

  1. function quick_sort($array){     
  2.   if (count($array) <= 1) return $array;      
  3.     
  4.   $key = $array[0];     
  5.   $left_arr = array();     
  6.   $right_arr = array();     
  7.   for ($i=1; $i<count($array); $i++){     
  8.     if ($array[$i] <= $key)     
  9.       $left_arr[] = $array[$i];     
  10.     else    
  11.       $right_arr[] = $array[$i];     
  12.   }     
  13.   $left_arr = quick_sort($left_arr);     
  14.   $right_arr = quick_sort($right_arr);      
  15.     
  16.   return array_merge($left_arrarray($key), $right_arr);     
  17. }   


幾種排序演算法的比較和選擇
1. 選取排序方法需要考慮的因素:
(1) 待排序的元素數目n;
(2) 元素本身資訊量的大小;
(3) 關鍵字的結構及其分佈情況;
(4) 語言工具的條件,輔助空間的大小等。
2. 小結:
(1) 若n較小(n <= 50),則可以採用直接插入排序或直接選擇排序。由於直接插入排序所需的記錄移動操作較直接選擇排序多,因而當記錄本身資訊量較大時,用直接選擇排序較好。
(2) 若檔案的初始狀態已按關鍵字基本有序,則選用直接插入或氣泡排序為宜。
(3) 若n較大,則應採用時間複雜度為O(nlog2n)的排序方法:快速排序、堆排序或歸併排序。 快速排序是目前基於比較的內部排序法中被認為是最好的方法。
(4) 在基於比較排序方法中,每次比較兩個關鍵字的大小之後,僅僅出現兩種可能的轉移,因此可以用一棵二叉樹來描述比較判定過程,由此可以證明:當檔案的n個關鍵字隨機分佈時,任何藉助於"比較"的排序演算法,至少需要O(nlog2n)的時間。
(5) 當記錄本身資訊量較大時,為避免耗費大量時間移動記錄,可以用連結串列作為儲存結構。


來源:http://blog.csdn.net/everysii/article/details/52366252

相關文章