程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php實現的常見排序算法匯總

php實現的常見排序算法匯總

編輯:關於PHP編程

     一、插入排序

    用文字簡單的描述,比如說$arr = array(4,2,4,6,3,6,1,7,9); 這樣的一組數字進行順序排序:
    那麼,首先,拿數組的第二個元素和第一元素比較,假如第一個元素大於第二元素,那麼就讓兩者位置互換,接下來,拿數組的第三個元素,分別和第二個,第一個元素比較,假如第三個元素小,那麼就互換。依次類推。這就是插入排序,它的時間頻度是:1+2+...+(n-1)=(n^2)/2。則它的時間復雜度為O(n^2).

    php實現代碼如下:

    01 <?php 02 function insertSort($arr){ 03    $count = count($arr); 04    if($count<2){ 05   return $arr;  06    } 07    for($i=1;$i<$count;$i++){ 08    $tmp = $arr[$i]; 09    $j=$i-1; 10    while(j>=0&&$arr[$j]<$arr[$i]){ 11   $arr[$i] = $arr[$j];            12   $arr[$j] = $tmp; 13   $j--; 14    } 15     } 16     return $arr;  17  } 18 ?>

    二、選擇排序

    選擇排序用語言描述的話,可以這樣,如:$arr = array(4,3,5,2,1);

    首先,拿第一個和後面所有的比,找出最小的那個數字,然後和第一個數組互換(當然,如果是第一個最小,那麼就不用互換了),接著循環,即:拿第二個和後面的比較,找出最小的數字,然後和第二個數字互換,依次類推,也就是說每次都是找出剩余最小的值。 可得到:第一次,時間頻度 是n, (第一個和後面的n-1個比較,找到最小的,再看是不是第一個,不是第一個的話進行互換) 在往後,依次是 減一 。 它的時間復雜度,也是O(n^2);

    php實現代碼如下:

    01 <?php 02 function selectSort($arr){ 03    04    $count = count($arr); 05    if($count<2){ 06   return $arr;  07    } 08    for($i=0;$i<$count;$i++){ 09    $min=$i; 10    for(j=$i+1;$j<$count;$j++){ 11   if($arr[$min]>$arr[$j]){ 12     $min = $j; //找到最小的那個元素的下標 13   } 14    } 15    if($min!=$i){//如果下標不是$i 則互換。 16    $tmp= $arr[$i];            17     $arr[$i] = $arr[$min]; 18     $arr[$min] = $tmp; 19     } 20     } 21     return $arr;  22  } 23 ?>

    三、冒泡排序  
        
    冒泡排序其實上是和選擇排序相比,並無明顯差別。都是找到最小的,放到最左端。依次循環解決問題。差別在於冒泡排序的交換位置的次數較多,而選擇排序則是找到最小的元素的下標,然後直接和最左端的交換位置。


    php實現代碼如下:

    01 <?php 02 function selectSort($arr){ 03    04    $count = count($arr); 05    if($count<2){ 06   return $arr;  07    } 08    for($i=0;$i<$count;$i++){ 09    for(j=$i+1;$j<$count;$j++){ 10   if($arr[$i]>$arr[$j]){ 11     $tmp= $arr[$i];            12     $arr[$i] = $arr[$i]; 13     $arr[$i] = $tmp; 14   } 15    } 16     } 17     return $arr;  18  } 19 ?>

    四、快速排序

    快速排序,用語言來形容的話,從數組中選擇一個值$a,然後和其余元素進行比較,比$a大的放到數組right中,反之,放到數組left中。然後將left right 分別進行遞歸調用,即:再細分left right ,最後進行數組的合並。

    php實現快速排序:

      01 <?php 02 function mySort($arr){ 03    04    $count = count($arr); 05    if($count<2){ 06   return $arr;  07    } 08    $key = $arr[0];//選擇第一個元素作為比較元素,可選其他 09     $left = array();        10     $right = array(); 11     for($i=1;$i<$count;$i++){ 12    if($key>=$arr[$i]){ 13   $left[] = $arr[$i];  14    }else{ 15   $right[] = $arr[$i]; 16     } 17     } 18     $left = mySort($left); 19     $right = mySort($right); 20     $result = array_merge($left,$right); 21     return $result;  22  } 23 ?>

    五、歸並排序

    其實歸並排序是一種拆分,合並的思想。和快速排序思想有共通之處,左邊一堆,右邊一堆,然後進行合並。通過遞歸實現排序。 區別之處呢?  他們的區別也是思想上本質的區別,快速排序的拆分,是選擇了特定的值進行大小比較,從而分為left 和 right 。也就是小的一堆放入left,大的一堆放入right。而後,小的left 再細分為left1  right1。。。。通過進行類似的遞歸完成排序。也就是說,一直細分下去,遞歸最末尾的left1就是最小值。

    而歸並排序,是從幾何上的左右切分,一直遞歸切分成2或者1的最小粒度的數組,然後才開始進行比較大小,然後合並。此處的比較大小是:兒子left的元素 和兒子的right元素 進行比較,而後進行排序合並成為父親left或者right。在此,直到拿到各自排序合並完成最後兩個數組:最起初的left 和right,也僅僅直到他們各自的順序,並不能確認整個數組的順序,還是需要通過最終的left right 比較後合並才能完成真正意義上的排序。

    01 <?php 02 function gbSort($arr){ 03     if(count($arr)<=1){return $arr;} 04     $min = floor(count($arr)/2);//取中間數字進行拆分 05     $left = array_slice($arr,0,$min); 06     $right = array_slice($arr,$min); 07     $left = gbSort($left); //遞歸 08     $right = gbSort($right); 09     return get_merge($left,$right);//調用排序合並函數進行合並 10 } 11 function get_merge($left,$right){ 12     while(count($left) && count($right)){ 13         $m[] = $left[0]>$right[0] ? array_shift($right) : array_shift($left); 14         //進行比較,小的移除,並且放入到數組$m中。 15     } 16     return arr_merge($m,$left,$right);//進行合並(由於不知道left right 哪個會為空,所以進行統一合並) 17 } 18    19 ?>

    六、堆排序

    本例中fixDown函數實現對某一個節點的向下調整,這裡默認的是起始節點為1,方便計算父子節點關系

    注:

    起始節點為1的父子關系: 父節點k, 子節點為2K、2k+1     子節點j, 父節點為 floor(j/2)  floor為向下取整
    起始節點為0的父子關系: 父節點k, 子節點為2K+1, 2k+2   子節點j, 父節點為 floor((j-1)/2)

    參數$k為調整點位置, $lenth為數組長度,也就是從1起始到最後一個節點的坐標.

      01 <?php 02 function fixDown(&$arr, $k, $lenth) 03 { 04   while(2*$k<=$lenth) { //只要當前節點有子節點, 就需要繼續該循環 05     $j = $k*2; 06     if ($j<$lenth && $arr[$j]<$arr[$j+1]) $j++;  // 只要子節點有右節點,且右節點比左節點大,那麼切換到右節點操作。 07     if ($arr[$j] < $arr[$k]) break; // 如果子節點都沒有父節點大, 那麼調整結束。 08     exch($arr[$j], $arr[$k]); 09      $k = $j; 10   } 11 } 12    13 function exch(&$a, &$b) { 14   $tmp = $a; $a = $b; $b = $tmp; 15 } 16    17 function headSort(&$arr) 18 { 19   $len = count($arr); 20   array_unshift($arr, NULL); 21   for($i=$len/2;$i>=1;$i--) { 22     fixDown($arr, $i, $len); 23   } 24   while($len>1) { 25     exch($arr[1], $arr[$len]); 26     fixDown($arr, 1, --$len); 27   } 28   array_shift($arr); 29 } 30 $arr = array(4,6,4,9,2,3); 31 headSort($arr); 32 ?>
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved