php 冒泡排序,快速排序,選擇排序,插入排序 代碼實例與複雜度分析

一 php代碼實例

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;
    }

選擇排序
簡述,假設數組有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) 。  這時還用冒泡算法。 明天再來看結果。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章