1. 程式人生 > >php 常用四種排序 冒泡,選擇,插入,快排

php 常用四種排序 冒泡,選擇,插入,快排

sel ray 一次 自己 public 如果 art dex 代碼

---恢復內容開始---

1冒泡排序。 【為描述方便,例子全面為升序排列】
簡述:假設數組有10個數字,從左向右。依次比較,如果前者大於後者,則兩兩交換。每一輪將冒泡一個最大數出來,依次循環,完成排序
流程描述
-- 第一次 a[0] 與 a[1] 比如果 a[0] > a[1] 則 a[0] 與 a[1] 交換,然後 a[1] 與 a[2] 交換,依次到 a[8] 與 a[9] 交換。 此輪過後 a[9] 必為 a[0-9] 中的最大值。
 第二次(此時 a[9]以是最大值) a[0] 與 a[1] 比如果 a[0] > a[1] 則 a[0] 與 a[1] 交換,然後 a[1] 與 a[2] 交換,依次到 a[7] 與 a[8] 交換。 此輪過後 a[8] 必為 a[0-8] 中的最大值。
第三次(此時 a[9]以是最大值,a[8]次大) a[0] 與 a[1] 比如果 a[0] > a[1] 則 a[0] 與 a[1] 交換,然後 a[1] 與 a[2] 交換,依次到 a[6] 與 a[7] 交換。 此輪過後 a[7] 必為 a[0-7] 中的最大值。
-------------- 如此反復,一次冒泡一個最大值出來。


//冒泡排序代碼示例
  public function bubbleSort($arr){  //冒泡排序
        $len = sizeof($arr);
        for( $i = 0; $i< $len - 1; $i++){    //冒第幾個泡

            for( $j = 0; $j < $len - $i - 1 ; $j++){  //未冒完泡的依次比較,找出最大值
                if( $arr[$j] > $arr[$j+1]){
                    $arr =    swap($arr , $j
, $j+1); } } } return $arr; } //將數組的第 i j 位互換。 //後面代碼略 public function swap($arr , $i , $j){ // $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; return $arr; }

2選擇排序
簡述,假設數組有10個數字,從左向右 1 到9 每個與右邊的所有數進行比較,找出右側最小的,並與之替換。
流程描述


-- 第一次 a[0] 逐個與 a[1] - a[9] 比對,找到最小值,然後 a[0]與a[0-9]中的最小值進行替換。替換後 a[0] 為數組最小值 (如果0 正好是最小,則不替換 )
第二次 此時a[0],以是最小值,進行下一步。a[1] 逐個與 a[2] - a[9] 比對,找到最小值,然後 a[1]與a[1-9]最小的進行替換。
第三次 此時a[0],以是最小值,a[1] 為數組次小值(前兩個元素已排好序) a[2] 逐個與 a[3] - a[9] 比對,找到最小值,然後 a[2]與那個a[2-9]最小值的進行替換。
............... 依次循環,完成排序。

//選擇排序代碼示例
function selectSort($arr){  //
        $len = sizeof($arr);
        for( $i = 0; $i< $len - 1; $i++){  //從左向右遍歷,每次找出 i 位的最小值.
$minIndex = $i; for( $j = $i+1; $j < $len ; $j++){ //遍歷 i 右邊的不斷的找出最小值。 if( $arr[$minIndex] > $arr[$j]){ $minIndex = $j; } } //位置交換 if( $i != $minIndex){ //把當次最左邊的與向右查找的最小值進行替換。 $arr = $this->swap( $arr , $i , $minIndex);; } } return $arr; }


3 快速排序 (重點)
簡述:
設置一個基數,然後對數組進行左右切割。(左邊比基數小,右邊大於等於基數) ,然後再對左邊數組做上述操作。 最後將左 數組 基數 右數據 進行歸並

 //快速排序算法   
 public function quickSort($arr){
        $len = sizeof($arr);
        if( $len <=1 ) return $arr;

        $base = $arr[0];  //基數

        $l_arr = array();  //左邊數組
        $r_arr = array();  //右邊數組
        for($i = 1;$i<$len ; $i++){
            if( $arr[$i] < $base){
                $l_arr[]= $arr[$i];
            }else{
                $r_arr[]=$arr[$i];
            }
        }
        $l_arr = quickSort($l_arr);
        $r_arr = quickSort($r_arr);
        return array_merge($l_arr , array($base) , $r_arr);
    }

4 插入排序 (附帶介紹,可以略過)
簡述,假設數組有10個數字,從數組第二個開始, 每次向左比較【左邊已是一個有序數組】依次向左找到自己的位置,一個一個比。
受制於語言能力,寫得很饒口。

-- 第一次 a[1] 與 a[0] 比,如果a[1] < a[0] 則 將a[0] 數據移至 a[1] 位 將 a[1] 的值插入到 a[0]位置上。

-- 第二次 a[2] (待插入值) 與 a[0] , a[1] (已經有序) 如果a[2](待插入值) > a[1] 則 a[2] (待插入值) 不動。 如果小於a[1] 則 將原 a[1] 數值移到 a[2] 中,a[2](待插入值) 的值放入到 a[1]中。 再與 a[0] 比,如果大於 a[0] 則 a[0]值放入到 a[1] 中。

public function insertSort($arr){
        $len = sizeof($arr);
        for( $i = 1; $i< $len ; $i++){
            $temp = $arr[$i];
       for( $j = $i-1; $j>=0; $j--){ //針對一個有序數據,依次找插入位
                if($temp < $arr[$j]){ //逐個插入。
                    $arr[$j+1] = $arr[$j];
                    $arr[$j] = $temp;
                }else{
                    break;
                }
            }
        }
        return $arr;
    }

寫在最後:要對大量數據,有量級的概念。 快排的復雜度是 O( N log N) ,冒泡排序是 O(N平方)
僅以1萬個數為例。 快排復雜度是 10000 * Log2 10000 約為 13* 萬 ,冒泡則是 1億。 相差約800倍性能。
如果是10萬個 快排則是 10萬 * log2 100000 約為 170萬 而冒泡則是100億。 瞬間差出約7000 位。

而10萬條數據,在真實場景下,真的不多。

如果說感受不明顯,就跑跑代碼體驗下。

/**性能調試。*/
function bench_profile($starttime , $flag = ‘‘){
    $endtime = explode(‘ ‘,microtime());
    $thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]);
    $thistime = round($thistime,3);
    return  $flag."-bench:".$thistime." sec";
}


  $start_time = explode(‘ ‘,microtime());
        echo     bench_profile($start_time)."<br/>";
            $arr = [];
            for($i=0;$i<10000;$i++){
                $arr[]= rand(1,100000);
            }
            $arr_insert = quickSort($arr);
        echo   bench_profile($start_time);
//1w條跑完時間 -bench:0.053 sec    冒泡算法。  約 45 秒
//10w條跑完時間 -bench:0.77 sec    冒泡算法    約 一個半小時。
//100萬條,跑完時間  16秒。 這時需要放開內存限制  ini_set("memory_limit",-1) 。  這時還用冒泡算法。 明天再來看結果。


技術分享圖片

php 常用四種排序 冒泡,選擇,插入,快排