归并排序 (php版 递归 自顶向下)

时间复杂度: O(nlogn)

简单图示:

​​​​​​​​​​​​​​

主要思路(宏观):

利用递归思想把一个无序数组拆分成一个一个的最基本的单元,然后通过解决最基本单元的问题求解

class MergeSort
{
    public function __construct()
    {
    }

    //归并算法总函数
    public function MergeSort(&$arr){
        $start = 0;
        $end = count($arr) - 1;
        $this->sort($arr,$start,$end);
    }

    public function sort(&$arr,$l,$r)
    {


        if ($l>=$r) return;

        $mid = floor(($l+$r)/2);
        $this->sort($arr,$l,$mid);
        $this->sort($arr,$mid+1,$r);
        $this->merge($arr,$l,$mid,$r);

    }

    /**
     * 方法1
     * @param $arr
     * @param $l
     * @param $mid
     * @param $r
     */
    public function merge(&$arr,$l,$mid,$r):void
    {
        $i = $l;        //第一个区间头
        $j = $mid+1;    //第二个区间头

        $temp = $arr;
        //每轮循环$arr[$k]的值
        for ($k=$l;$k<=$r;$k++){
            //先判断$i,$j防止越界 在判断$arr[$i] 和 $arr[$j]的大小 因为是 l 和 r 有$l的数组偏移量
            if ($i>$mid){
               $arr[$k] = $temp[$j-$l];
               $j++;
            }elseif ($j>$r){
                $arr[$k] = $temp[$i-$l];
                $i++;
            }elseif ($temp[$i-$l]<=$temp[$j-$l]){
                $arr[$k] = $temp[$i-$l];
                $i++;
            }else{
                $arr[$k] = $temp[$j-$l];
                $j++;
            }
        }

    }

    /**
     * 方法2
     * @param $arr
     * @param $l
     * @param $mid
     * @param $r
     */
    public function merge2(&$arr,$l,$mid,$r):void
    {
        $i = $l;
        $j=$mid + 1;
        $k = $l;
        $temparr = array();

        while($i!=$mid+1 && $j!=$r+1)
        {
            if($arr[$i] >= $arr[$j]){
                $temparr[$k++] = $arr[$j++];
            }
            else{
                $temparr[$k++] = $arr[$i++];
            }
        }

        //将第一个子序列的剩余部分添加到已经排好序的 $temparr 数组中
        while($i != $mid+1){
            $temparr[$k++] = $arr[$i++];
        }
        //将第二个子序列的剩余部分添加到已经排好序的 $temparr 数组中
        while($j != $r+1){
            $temparr[$k++] = $arr[$j++];
        }
        for($i=$l; $i<=$r; $i++){
            $arr[$i] = $temparr[$i];
        }
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值