PHP排序算法之归并排序(Merging Sort)实例详解


Posted in PHP onApril 21, 2018

本文实例讲述了PHP排序算法之归并排序(Merging Sort)。分享给大家供大家参考,具体如下:

基本思想:

归并排序:就是利用归并(合并)的思想实现的排序方法。它的原理是假设初始序列含有 n 个元素,则可以看成是 n 个有序的子序列,每个子序列的长度为 1,然后两两归并,得到 ⌈ n / 2⌉ (⌈ x ⌉ 表示不小于 x 的最小整数)个长度为 2 或 1 的有序序列;再两两归并,······,如此重复,直至得到一个长度为 n 的有序序列为止,这种排序方法就成为 2 路归并排序。

一、归并的过程:

a[i] 取 a 数组的前部分(已经排好序),a[j] 取 a 数组的后部分(已经排好序)

r 数组存储排好序的 a 数组

比较 a[i]和 a[j] 的大小,若 a[i] ≤ a[j],则将第一个有序表中的元素 a[i] 复制到 r[k] 中,并令 i 和 k 分别加上 1;否则将第二个有序表中的元素 a[j] 复制到 r[k] 中,并令 j 和 k 分别加上 1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到 r 中从下标 k 到下标 t 的单元。归并排序的算法我们通常用递归实现,先把待排序区间 [s,t] 以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间 [s,t]。

二、归并操作:

归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。

如 设有数列{6,202,100,301,38,8,1}

初始状态:6 , 202 , 100 , 301 , 38 , 8,1

第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;

第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;

第三次归并后:{1,6,8,38,100,202,301},比较次数:4;

总的比较次数为:3+4+4=11,;

逆序数为14;

三、算法描述:

归并操作的工作原理如下:

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

重复步骤3直到某一指针超出序列尾

将另一序列剩下的所有元素直接复制到合并序列尾

PHP排序算法之归并排序(Merging Sort)实例详解

算法实现:

我们先来看看主函数部分:

//交换函数
function swap(array &$arr,$a,$b){
  $temp = $arr[$a];
  $arr[$a] = $arr[$b];
  $arr[$b] = $temp;
}
//归并算法总函数
function MergeSort(array &$arr){
  $start = 0;
  $end = count($arr) - 1;
  MSort($arr,$start,$end);
}

在总函数中,我们只调用了一个 MSort() 函数,因为我们要使用递归调用,所以将 MSort() 封装起来。

下面我们来看看 MSort() 函数:

function MSort(array &$arr,$start,$end){
  //当子序列长度为1时,$start == $end,不用再分组
  if($start < $end){
    $mid = floor(($start + $end) / 2); //将 $arr 平分为 $arr[$start - $mid] 和 $arr[$mid+1 - $end]
    MSort($arr,$start,$mid);  //将 $arr[$start - $mid] 归并为有序的$arr[$start - $mid]
    MSort($arr,$mid + 1,$end);  //将 $arr[$mid+1 - $end] 归并为有序的 $arr[$mid+1 - $end]
    Merge($arr,$start,$mid,$end);    //将$arr[$start - $mid]部分和$arr[$mid+1 - $end]部分合并起来成为有序的$arr[$start - $end]
  }
}

上面的 MSort() 函数实现将数组分半再分半(直到子序列长度为1),然后将子序列合并起来。

现在是我们的归并操作函数 Merge() :

//归并操作
function Merge(array &$arr,$start,$mid,$end){
  $i = $start;
  $j=$mid + 1;
  $k = $start;
  $temparr = array();
  while($i!=$mid+1 && $j!=$end+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 != $end+1){
    $temparr[$k++] = $arr[$j++];
  }
  for($i=$start; $i<=$end; $i++){
    $arr[$i] = $temparr[$i];
  }
}

到了这里,我们的归并算法就完了。我们调用试试:

$arr = array(9,1,5,8,3,7,4,6,2);
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(nlogn)

归并算法是一种稳定的排序算法。

本文参考自《大话数据结构》,在此仅作记录,方便以后查阅,大神勿喷!

PHP 相关文章推荐
dedecms模板标签代码官方参考
Mar 17 PHP
PHP面向对象分析设计的61条军规小结
Jul 17 PHP
PHP MemCached 高级缓存应用代码
Aug 05 PHP
利用浏览器的Javascript控制台调试PHP程序
Jan 08 PHP
php实现天干地支计算器示例
Mar 14 PHP
PHP和javascript常用正则表达式及用法实例
Jul 01 PHP
浅析PHP编程中10个最常见的错误
Aug 08 PHP
smarty简单分页的实现方法
Oct 27 PHP
ThinkPHP连接数据库的方式汇总
Dec 05 PHP
CI框架数据库查询缓存优化的方法
Nov 21 PHP
实现php删除链表中重复的结点
Sep 27 PHP
laravel 执行迁移回滚示例
Oct 23 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
Apr 21 #PHP
Laravel模型间关系设置分表的方法示例
Apr 21 #PHP
PHP排序算法之基数排序(Radix Sort)实例详解
Apr 21 #PHP
PHP排序算法之堆排序(Heap Sort)实例详解
Apr 21 #PHP
PHP实现Huffman编码/解码的示例代码
Apr 20 #PHP
PHP排序算法之希尔排序(Shell Sort)实例分析
Apr 20 #PHP
PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
Apr 20 #PHP
You might like
php xml文件操作实现代码(二)
2009/03/20 PHP
PHP生成UTF8文件的方法
2010/05/15 PHP
PHP学习笔记之三 数据库基本操作
2011/01/17 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
PHP实现根据图片色界在不同位置加水印的方法
2015/08/08 PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
2016/06/13 PHP
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
js写的方法实现上传图片之后查看大图
2014/03/05 Javascript
调用jQuery滑出效果时闪烁的解决方法
2014/03/27 Javascript
JavaScript中的Object对象学习教程
2016/05/20 Javascript
基于Node.js + WebSocket打造即时聊天程序嗨聊
2016/11/29 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
微信小程序录音与播放录音功能
2017/12/25 Javascript
在vue 中使用 less的教程详解
2018/09/26 Javascript
微信小程序实现的五星评价功能示例
2019/04/25 Javascript
微信小程序websocket实现即时聊天功能
2019/05/21 Javascript
JS实现打砖块游戏
2020/02/14 Javascript
JS实现点击掉落特效
2021/01/29 Javascript
python创建线程示例
2014/05/06 Python
Python程序设计入门(4)模块和包
2014/06/16 Python
python中list循环语句用法实例
2014/11/10 Python
Python+OpenCV实现车牌字符分割和识别
2018/03/31 Python
详解Python安装scrapy的正确姿势
2018/06/26 Python
Python单元测试简单示例
2018/07/03 Python
解决python中0x80072ee2错误的方法
2020/07/19 Python
selenium自动化测试入门实战
2020/12/21 Python
瑞典的玛丽小姐:Miss Mary of Sweden
2019/02/13 全球购物
Servlet方面面试题
2016/09/28 面试题
合作意向书范本
2014/03/31 职场文书
2013年最新自荐信范文
2014/06/23 职场文书
装修施工安全责任书
2014/07/24 职场文书
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
国庆横幅标语
2014/10/08 职场文书
转正申请报告格式
2015/05/15 职场文书
小学五年级班主任工作经验交流材料
2015/11/02 职场文书
《藏戏》教学反思
2016/02/23 职场文书