PHP 归并排序

1、原理
归并排序是一种概念上最简单的排序算法,与快速排序一样,归并排序也是基于分治法的。归并排序将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将他们合并成一个子序列。合并两个子序列的过程也就是两路归并。

2、复杂度
归并排序是一种稳定的排序算法,归并排序的主要问题在于它需要一个与待排序数组一样大的辅助数组空间。由于归并排序每次划分时两个子序列的长度基本一样,所以归并排序最好、最差和平均时间复杂度都是nlog2n
通过下图非常容易看懂归并排序的过程:

 

//递归拆分,直到剩下一个元素,我们认为他是有序的
function fen(&$arr, $start, $end)
{
    if ($start < $end) {
        $mid = floor(($start + $end) / 2);
        fen($arr,$start,$mid);
        fen($arr,$mid+1,$end);
        //拆分完以后需要两两合并
        merge($arr,$start,$mid,$end);
    }
}

function merge(&$arr,$start,$mid,$end){
    $i = $start;
    $j = $mid+1;
    $tmp = [];
    //两两循环比较,当左边的第一个元素小于右边的第一个元素,将左边第一个元素放入临时数组
    //然后拿左边数组的第二个元素与右边数组的第一个元素比较,如果左边第二个元素大于右边第一个元素,将右边第一个放入临时数组
    //依次比较,知道有一边的元素取完为止
    while($i<=$mid && $j<=$end){
        if($arr[$i] <= $arr[$j]){
            $tmp[] = $arr[$i++];
        }else{
            $tmp[] = $arr[$j++];
        }
    }
    //将左边剩余的元素放入临时数组
    while($i<=$mid){
        $tmp[] = $arr[$i++];
    }
    //将右边剩余的元素放入临时数组
    while($j<=$end){
        $tmp[] = $arr[$j++];
    }
    //因为前面操作的都是临时数组,而归并操作的事原数组,所以还要把临时数组中的元素放入原数组中
    for($k = 0;$k<count($tmp);$k++){
        $arr[$k+$start] = $tmp[$k];
    }
}

测试:

$args = [15, 20, 3, 8, 55, 6, 88, 33, 21, 19, 36, 56, 77];

$start = 0;
$end = count($args) - 1;
fen($args,$start,$end);
echo "<pre>";
print_r($args);

输出结果为:

参考原文:https://blog.csdn.net/qq_36442947/article/details/81612870 

posted @ 2019-07-23 15:14  独孤靖云  阅读(965)  评论(0编辑  收藏  举报