[100天每天一個算法--第12天] PHP實現歸併排序算法

摘自百度百科: 歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序

代碼如下:

<?php
/*
歸併排序
 */
function MergeSort(&$arr = array()) {
	$start = 0;
	$end = count($arr)-1;
    Msort($arr, $start, $end);
}
//歸併算法
function Msort(&$arr = array(),$start,$end) {
	if ($start < $end) {//如果遞歸分組個數=1 即$start=$end則停止分治
        $mid = floor(($start+$end)/2);//求出中間值
        Msort($arr,$start,$mid);//遞歸對數組左邊的排序
        Msort($arr,$mid+1,$end);//遞歸對數組右邊的排序
        Merge($arr,$start,$mid,$end);//將排完序的倆部分數組合並然後排序
	}
}
function Merge(&$arr=array(),$start,$mid,$end) {
    $i = $start;
    $j = $mid+1;
    $k = $start;
    $temarr = array();
    while($i!=$mid+1 && $j!=$end+1) {//定義邊界
        if ($arr[$i] >= $arr[$j]) {//比較兩邊子序列元素誰小,小的放進臨時數組,然後鍵加1
            $temarr[$k++] = $arr[$j++];
        } else {
            $temarr[$k++] = $arr[$i++];
        }
    }
    while($i!=$mid+1) {
    	$temarr[$k++] = $arr[$i++];//把左邊子序列沒有比較完的元素插入到臨時數組
    }
    while($j!=$end+1) {
    	$temarr[$k++] = $arr[$j++];//把右邊子序列沒有比較完的元素插入到臨時數組
    }
    for ($i=$start; $i<=$end; $i++) { 
    	$arr[$i] = $temarr[$i];//把元素複製到原數組
    }
}
$arr = [2,5,1,3,6,4,8,7,9];
MergeSort($arr);
var_dump($arr);

輸出結果:
array(9) { [0]=>int(1) [1]=> int(2) [2]=>int(3) [3]=> int(4) [4]=>int(5) [5]=>int(6)
[6]=>int(7)[7]=>int(8) [8]=>int(9) }
時間複雜度:O(n log n)
空間複雜度:O(n)

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