1.概念
归并排序是建立在归并操作上的一种有效的排序算法,该算法是分治法的一个典型应用。将已有序的子序列合并,得到完全有序的序列,即先使每个子序列有序,在使子序列段间有序。若将两个有序表合并为一个有序表,称为二路归并。
2.图解
如图,从下往上,每一步都需将两个已经有序的子序列合并成一个大的有序数组
3.代码实现
//合并两个有序数组
function merge(&$arr, $low, $mid, $high){
$temp = $arr; //生成一个临时数组,和原数组一模一样,方便后面的比较
$i = $low;
$j = $mid+1;
while ($low<=$mid && $j<=$high) {
if ($temp[$low]>$temp[$j]) {
$arr[$i++] = $temp[$j++];
}else {
$arr[$i++] = $temp[$low++];
}
}
//剩下其中一个数组的情况
while ($low<=$mid) {
$arr[$i++] = $temp[$low++];
}
//剩下另一个数组的情况
while ($j<=$high) {
$arr[$i++] = $temp[$j++];
}
unset($temp); //释放临时数组
}
//递归调用
function merge_sort(&$arr,$low,$high) {
if ($low>=$high) return; //结束条件
$mid = (int)(($low+$high)/2);
merge_sort($arr,$low,$mid);
merge_sort($arr,$mid+1,$high);
merge($arr,$low,$mid,$high);
}
$arr = [12,56,98,32,16,34,2,9,1];
$len = count($arr);
merge_sort($arr, 0, $len-1);
dump($arr);
4.效果展示
5.复杂度分析
归并排序的时间复杂度为 O(nlogn),空间复杂度为 O(n)。但是它是稳定的排序算法,因为两两的归并,它们之间是基于相邻元素之间的比较。