PHP排序算法之冒泡排序(Bubble Sort)实现方法详解


Posted in PHP onApril 20, 2018

本文实例讲述了PHP排序算法之冒泡排序(Bubble Sort)实现方法。分享给大家供大家参考,具体如下:

基本思想:

冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

最简单排序实现:

我们先来看看在没有学习各种排序方法前经常使用的排序方法(至少我是这样。。。。):

//这里使用了类型提示(type hint) array,不熟悉或者不习惯的同学大可去掉,不影响运算结果
function MySort(array &$arr){
  $length = count($arr);
  for($i = 0;$i < $length - 1;$i ++){
    for($j = $i + 1;$j < $length;$j ++){
      //将小的关键字放前面
      if($arr[$i] > $arr[$j]){
        $temp = $arr[$i];
        $arr[$i] = $arr[$j];
        $arr[$j] = $temp;
      }
    }
  }
}
$arr = array(9,1,5,8,3,7,4,6,2);
MySort($arr);
print_r($arr);

上面的这段代码严格意义上说,不算是标准的冒泡排序,因为它不满足“两两比较相邻记录”的冒泡排序思想,它仅仅是一个简单的交换排序。思路不过是:从第一个关键字开始,将每一位关键字与它后面的所有关键字相比较,交换得到其中的最小值。但这个算法是非常低效的。

冒泡排序算法:

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为数组中越大的元素会由于一次次排序后逐渐“沉”到数组的后面,而越小的元素会逐渐“浮”到数组的前面,故名。

冒泡排序算法的运作如下:(从后往前)

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

看文字描述不一定看得懂,看代码吧:

//交换方法
function swap(array &$arr,$a,$b){
  $temp = $arr[$a];
  $arr[$a] = $arr[$b];
  $arr[$b] = $temp;
}
//冒泡排序
function BubbleSort(array &$arr){
  $length = count($arr);
  for($i = 0;$i < $length - 1;$i ++){
    //从后往前逐层上浮小的元素
    for($j = $length - 2;$j >= $i;$j --){
      //两两比较相邻记录
      if($arr[$j] > $arr[$j + 1]){
        swap($arr,$j,$j+1);
      }
    }
  }
}

冒泡排序算法改进:

《大话数据结构》果然是本好书,还给我们介绍了冒泡排序算法的改进,这里我就直接搬它的陈述:

上面的冒泡排序算法是否还可以优化呢?答案是肯定的。试想一下,如果我们待排序的序列是{2,1,3,4,5,6,7,8,9},也就是说,除了第一和第二个关键字需要交换外,别的都已经是正常的顺序了。当 i = 0 时,交换了 2 和 1 ,此时的序列已经是有序的了,但是算法仍然不依不挠地将 i = 2 到 9 以及每个循环中的 j 循环都执行了一遍,尽管并没有交换数据,但是之后的大量比较还是大大地多余了。
当 i = 2 时,我们已经对 9 与 8,8 与 7,·······,3 与 2 做了比较,没有任何数据交换,这就说明此序列已经有序,不需要再继续后面的循判断工作了(后面的工作也是不会发生任何数据交换,再做也是没有意义了)。为了实现这个想法,我们需要改进一下代码,增加一个标记变量 flag 来实现这一算法的改进:

//交换方法
function swap(array &$arr,$a,$b){
  $temp = $arr[$a];
  $arr[$a] = $arr[$b];
  $arr[$b] = $temp;
}
/冒泡排序的优化(如果某一次循环的时候没有发生元素的交换,则整个数组已经是有序的了)
function BubbleSort1(array &$arr){
  $length = count($arr);
  $flag = TRUE;
  for($i = 0;($i < $length - 1) && $flag;$i ++){
    $flag = FALSE;
    for($j = $length - 2;$j >= $i;$j --){
      if($arr[$j] > $arr[$j + 1]){
        swap($arr,$j,$j+1);
        $flag = TRUE;
      }
    }
  }
}

代码改动的关键就是在 i 变量的for循环中,增加了对flag是否为 true 的判断,经过这样的改进,冒泡排序在性能上就有了一些提升,可以避免因已经有序的情况下的无意义循环判断。

冒泡算法总的时间复杂度是 O(n^2)

冒泡排序是稳定排序。

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

PHP 相关文章推荐
一个简单的自动发送邮件系统(三)
Oct 09 PHP
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
Aug 26 PHP
PHP及Zend Engine的线程安全模型分析
Nov 10 PHP
解析php扩展php_curl.dll不加载的解决方法
Jun 26 PHP
linux下使用crontab实现定时PHP计划任务失败的原因分析
Jul 05 PHP
PHP中捕获超时事件的方法实例
Feb 12 PHP
php中使用base HTTP验证的方法
Apr 20 PHP
php实现模拟登陆方正教务系统抓取课表
May 19 PHP
两种php给图片加水印的实现代码
Apr 18 PHP
PHP常用设计模式之委托设计模式
Feb 13 PHP
微信自定义分享php代码分析
Nov 24 PHP
微信推送功能实现方式图文详解
Jul 12 PHP
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
Apr 20 #PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
Apr 20 #PHP
Laravel 加载第三方类库的方法
Apr 20 #PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 #PHP
详解php curl带有csrf-token验证模拟提交方法
Apr 18 #PHP
php-app开发接口加密详解
Apr 18 #PHP
PHPMAILER实现PHP发邮件功能
Apr 18 #PHP
You might like
Ubuntu12下编译安装PHP5.3开发环境
2015/03/27 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
Yii2选项卡的简单使用
2017/05/26 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
2019/10/10 PHP
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
javascript实现验证身份证号的有效性并提示
2015/04/30 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
NodeJS连接MongoDB数据库时报错的快速解决方法
2016/05/13 NodeJs
node.js express中app.param的用法详解
2017/07/16 Javascript
vue引入swiper插件的使用实例
2017/07/19 Javascript
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
一文让你彻底搞清楚javascript中的require、import与export
2017/09/24 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
2019/09/03 Javascript
[36:14]DOTA2上海特级锦标赛D组小组赛#1 EG VS COL第二局
2016/02/28 DOTA
[02:23]1个至宝=115个英雄特效 最“绿”至宝拉比克“魔导师密钥”登场
2018/12/29 DOTA
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
2014/06/10 Python
opencv python 基于KNN的手写体识别的实例
2018/08/03 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
Python3.7 dataclass使用指南小结
2019/02/22 Python
Python模块、包(Package)概念与用法分析
2019/05/31 Python
Python csv文件的读写操作实例详解
2019/11/19 Python
Pycharm+Python工程,引用子模块的实现
2020/03/09 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
python IP地址转整数
2020/11/20 Python
Django视图类型总结
2021/02/17 Python
SQL中where和having的区别
2012/06/17 面试题
英语专业应届生求职信范文
2013/11/15 职场文书
远程教育心得体会
2014/01/03 职场文书
幼儿教师演讲稿
2014/05/06 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
学会掌握自己命运的十条黄金法则:
2019/08/08 职场文书
有关花店创业的计划书模板
2019/08/27 职场文书
七个非常实用的Python工具包总结
2021/06/15 Python
python turtle绘图命令及案例
2021/11/23 Python
CSS使用伪类控制边框长度的方法
2022/01/18 HTML / CSS
Python使用华为API为图像设置多个锚点标签
2022/04/12 Python