常用的 PHP 搜尋排序算演算法

rufo發表於2017-07-15
  • 順序查詢
    $arr=array(46,90,900,0,-1);
    //這是按順序查詢
    function search(&$arr,$findVal){     
    $flag=false;
    for($i=0;$i<count($arr);$i++){
        if($findVal==$arr[$i]){
           echo "找到了,下標為=$i";
           $flag=true;
           break;
           }
        }
     if(!$flag){
         echo "查無此數";
     }
    }
  • 二分查詢(取半,向上取整比較,比較值大於中間值則最小值等於中間值+1,反之亦然)
        /**二分查詢:查詢一個值在陣列中的位置
    * @$arr:操作的陣列,前提是按順序排列
    * @$val:查詢的值
    * @$low:查詢的起始位置,預設從陣列的第一個數找起
    * @hight:查詢的結束位置
    **/
    Function binarySearch($arr, $val, $hight, $low=0){
            while($low<= $hight){
                    $mid= ceil($low+ ($hight- $low) / 2);
                    if($arr[$mid] == $val){
                            return$mid;
                    }elseif($arr[$mid] > $val){
                            $hight= $mid-1;
                    }else{
                            $low= $mid+1;
                    }
            }
            return-1;
    }
    //產生一個陣列
    $arr= range(0,20);
    //查詢的起始位置
    $low= 0;
    //查詢的結束位置
    $hight= count($arr) - 1;
    //查詢的值
    $findVal= rand(0, 20);
    $index= binarySearch($arr, $findVal, $hight, $low);
    printf("查詢的值 '%d' 在陣列中的下標 '%s'", $findVal, $index);
  • 氣泡排序
    思路分析:在要排序的一組數中,對當前還未排好的序列,從前往後對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即,每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。
        程式碼實現:
        $arr=array(1,43,54,62,21,66,32,78,36,76,39);  
        function bubbleSort($arr)
        {  
            $len=count($arr);
            //該層迴圈控制 需要冒泡的輪數
            for($i=1;$i<$len;$i++)
            { 
                for($k=0;$k<$len-$i;$k++)//$len-$i比較的次數
                {
                     if($arr[$k]>$arr[$k+1])//前面數大於後面就交換
                        {
                                $tmp=$arr[$k+1];
                                $arr[$k+1]=$arr[$k];
                                $arr[$k]=$tmp;
                        }
                 }
            }
            return $arr;
        }

- 選擇排序 (先選出最小放在第一個,再選出最小放在第二個)
思路分析:在要排序的一組數中,選出最小的一個數與第一個位置的數交換。然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後一個數比較為止。

程式碼實現:
        function selectSort($arr) {
                     //雙重迴圈完成,外層控制輪數,內層控制比較次數
                $len=count($arr);
                for($i=0; $i<$len-1; $i++) {
                        $p = $i;//每次迴圈先假設最小的值在第一個
                        for($j=$i+1; $j<$len; $j++) {  //$arr[$p] 是當前已知的最小值
                                if($arr[$p] > $arr[$j]) {
                                             $p = $j;   //比較發現小的,記錄下最小值的位置;
                                }
                        }
                        //最小值儲存到$p中。如果最小值的位置與當前假設的位置$i不同,則位置互換。
                        if($p != $i) {
                                $tmp = $arr[$p];
                                $arr[$p] = $arr[$i];
                                $arr[$i] = $tmp;
                        }
                }
                return $arr;    //返回最終結果
        }
  • 插入排序
    思路分析:在要排序的一組數中,假設前面的數已經是排好順序的,現在要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反覆迴圈,直到全部排好順序。
    程式碼實現:
    function insertSort($arr) {
            $len=count($arr); 
            for($i=1, $i<$len; $i++) {
                    $tmp = $arr[$i];//temp是要比較的資料
                    //內層迴圈實現比較並插入
                    for($j=$i-1;$j>=0;$j--) {//第一個數已經排好序
                            if($tmp < $arr[$j]) {
                                    //發現插入的元素要小,交換位置,將後邊的元素與前面的元素互換
                                    $arr[$j+1] = $arr[$j];
                                    $arr[$j] = $tmp;
                            } else {
                                    //如果碰到不需要移動的元素,由於是已經排序好是陣列,則前面的就不需要再次比較了。
                                    break;
                            }
                    }
            }
            return $arr;
    } 
  • 快速排序 (第一元素為基準,遞迴折半排序,每次排序array_merge)
    思路分析:選擇一個基準元素,通常選擇第一個元素或者最後一個元素。通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素。此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞迴地排序劃分的兩部分。
    程式碼實現:
    function quickSort($arr) {
            //先判斷是否需要繼續進行
            $length = count($arr);
            if($length <= 1)   return $arr;
            $base_num = $arr[0]; //選擇第一個元素作為基準
            $left_array = array();  //小於基準的
            $right_array = array();  //大於基準的
            //遍歷除了標尺外的所有元素,按照大小關係放入兩個陣列內
            for($i=1; $i<$length; $i++) {
                    if($base_num > $arr[$i]) {
                            //放入左邊陣列
                            $left_array[] = $arr[$i];
                    } else {
                            //放入右邊
                            $right_array[] = $arr[$i];
                    }
            }
            //再分別對左邊和右邊的陣列進行相同的排序處理方式遞迴呼叫這個函式
            $left_array = quick_sort($left_array);
            $right_array = quick_sort($righ·t_array);
            //合併
            return array_merge($left_array, array($base_num), $right_array);
    }
  • 如果可以,我要變成光

相關文章