1. 程式人生 > >php幾種常用演算法

php幾種常用演算法

寫一下幾種常見排序演算法,清一下腦子

歸併排序


/**
 * Created by PhpStorm.
 * User: leon
 * Date: 2018/3/14
 * Time: 下午2:37
 */

function mergeSort(&$arr) {
    $len = count($arr);//求得陣列長度
    mSort($arr, 0, $len-1);
    return $arr;
}
//實際實現歸併排序的程式
function mSort(&$arr, $left, $right) {
    if($left < $right) {
        //說明子序列記憶體在多餘1個的元素,那麼需要拆分,分別排序,合併
//計算拆分的位置,長度/2 去整 $center = floor(($left+$right) / 2); //遞迴呼叫對左邊進行再次排序: mSort($arr, $left, $center); //遞迴呼叫對右邊進行再次排序 mSort($arr, $center+1, $right); //合併排序結果 mergeArray($arr, $left, $center, $right); } } //將兩個有序數組合併成一個有序陣列 function mergeArray(&$arr
, $left, $center, $right)
{
//設定兩個起始位置標記 $a_i = $left; $b_i = $center+1; while($a_i<=$center && $b_i<=$right) { //當陣列A和陣列B都沒有越界時 if($arr[$a_i] < $arr[$b_i]) { $temp[] = $arr[$a_i++]; } else { $temp[] = $arr[$b_i++]; } } //判斷 陣列A內的元素是否都用完了,沒有的話將其全部插入到C陣列內:
while($a_i <= $center) { $temp[] = $arr[$a_i++]; } //判斷 陣列B內的元素是否都用完了,沒有的話將其全部插入到C陣列內: while($b_i <= $right) { $temp[] = $arr[$b_i++]; } //將$arrC內排序好的部分,寫入到$arr內: for($i=0, $len=count($temp); $i<$len; $i++) { $arr[$left+$i] = $temp[$i]; } } $SortArr = array(2,9,1,8,3,8); $res = mergeSort($SortArr); print_r($res);

選擇排序

/**
 * Created by PhpStorm.
 * User: leon
 * Date: 2018/3/13
 * Time: 下午6:44
 */

/*
* 思路:
* 每一次從待排序的資料元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。
* 選擇排序是不穩定的排序方法(比如序列[5, 5, 3]第一次就將第一個[5]與[3]交換,導致第一個5挪動到第二個5後面)
*/
function selectSort(...$array){
    $temp = 0;
    for($i = 0;$i < count($array) - 1;$i++){
        $minVal = $array[$i]; //假設$i就是最小值
        $minValIndex = $i;
        for($j = $i+1;$j < count($array);$j++){
            if($minVal > $array[$j]){ //從小到大排列
                $minVal = $array[$j]; //找最小值
                $minValIndex = $j;
            }
        }
        $temp = $array[$i];
        $array[$i] = $array[$minValIndex];
        $array[$minValIndex] = $temp;

        print_r($array);
    }
    return $array;
}
$res =  selectSort(2,9,1,8,3,8);
var_dump($res);

插入排序

/**
 * Created by PhpStorm.
 * User: leon
 * Date: 2018/3/13
 * Time: 下午6:27
 */
/**
 * @param array ...$args
 * @return array
 * 從元素 1 開始作為插入數字 , i-1 和 i 比,換i和 i-1 位,while 再把i-2和 i-1 新的insertValue比
 * 直到不滿足while,或者到頭 ,還需要比一下index+1是否等於當前迴圈次數,
 * 來判斷是否迴圈超過1次,這樣可以把最左邊用insert補全
 */

function InsertSort(...$args){
    print_r($args);
    for ($i = 1;$i < count($args); $i++){
        $insertVal = $args[$i]; //$insertVal是準備插入的數
        var_dump($i);
        var_dump('準備插入:'.$insertVal);
        print_r('while之前');
        print_r($args);

        $insertIndex = $i - 1; //1
        while( $insertIndex >= 0 && $insertVal < $args[$insertIndex] ){
            var_dump('進入while');
            $args[$insertIndex + 1] = $args[$insertIndex]; //將陣列往後挪
            $insertIndex--;

        }
        var_dump('while之後');
        print_r($args);

        if($insertIndex + 1 !== $i){//迴圈 > 1次時,會觸發,將插入值,放在最前面
            $args[$insertIndex + 1] = $insertVal;
        }
        var_dump('if之後');
        print_r($args);

    }
    return $args;
}


(InsertSort(2,9,1,8,3,8,3,2,2));

快速排序

/**
 * Created by PhpStorm.
 * User: leon
 * Date: 2018/3/13
 * Time: 下午4:51
 */

function QuickSort($args){


    //這裡要加一個限制,不然無限遞迴了
    if (!isset($args[1])) return $args;

    $mid = $args[0];//分割關鍵詞 。小的放一個 大的放一個
    $leftArr = array();
    $rightArr = array();

    foreach ($args as $value){
        if ($value > $mid) $rightArr[] = $value;
        if ($value < $mid) $leftArr[] = $value;
    }

    $leftArr = QuickSort($leftArr);
    $leftArr[] = $mid;
    $rightArr = QuickSort($rightArr);

    return array_merge($leftArr,$rightArr);

}

$rt = array(6,3,2,8,11,1);
print_r(QuickSort($rt));

///*
//* 思路:
//* 通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,
//* 然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
//* */
//function quickSort1($array){
//    if(!isset($array[1]))  return $array;
//    $mid = $array[0]; //獲取一個用於分割的關鍵字,一般是首個元素
//    $leftArray = array();
//    $rightArray = array();
//    foreach($array as $v){
//        if($v > $mid)
//            $rightArray[] = $v; //把比$mid大的數放到一個數組裡
//        if($v < $mid)
//            $leftArray[] = $v; //把比$mid小的數放到另一個數組裡
//    }
//    $leftArray = quickSort($leftArray); //把比較小的陣列再一次進行分割
//    $leftArray[] = $mid; //把分割的元素加到小的陣列後面,不能忘了它哦
//    $rightArray = quickSort($rightArray); //把比較大的陣列再一次進行分割
//    return array_merge($leftArray,$rightArray); //組合兩個結果
//}
//$arr= array(6,3,8,2,9,1);
//$res = quickSort($arr);
//var_dump($res);

氣泡排序

/**
 * Created by PhpStorm.
 * User: leon
 * Date: 2018/3/13
 * Time: 下午4:06
 */

function BubbleSort(...$args){
    $count = count($args);
    $temp = 0;

    //外層控制排序輪次
    for ($i = 0; $i < $count-1;$i++ ){
        //內層控制每輪比較次數
        for ($j = 0;$j < $count-$i-1;$j++){
            if ($args[$j] > $args[$j+1]){
                $temp = $args[$j];
                $args[$j] = $args[$j+1];
                $args[$j+1] = $temp;
            }
        }
    }
    return $args;
}

print_r(BubbleSort(2323,22,2,3,5,4,2,3));


總結:
1. 插入排序:穩定,O(n2)
2. 氣泡排序:穩定,O(n2) 一次長度減少1
3. 快排:不穩定。O(nlogn)最差 o(n2) ,二分排序,查詢減半
4. 選擇排序:不穩定:O(n2)
5. 歸併排序:O(n log n)