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 相关文章推荐
php学习 字符串课件
Jun 15 PHP
php Http_Template_IT类库进行模板替换
Mar 19 PHP
PHP 全角转半角实现代码
May 16 PHP
PHP中strtotime函数使用方法详解
Nov 27 PHP
解决phpmyadmin中缺少mysqli扩展问题的方法
May 06 PHP
实现获取http内容的php函数分享
Feb 16 PHP
php验证session无效的解决方法
Nov 04 PHP
php调用mysql存储过程实例分析
Dec 29 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
Jun 11 PHP
PHP levenshtein()函数用法讲解
Mar 08 PHP
PHP中遍历数组的三种常用方法实例分析
Jun 24 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
Dec 31 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
傻瓜化配置PHP环境――Appserv
2006/12/13 PHP
PHP项目开发中最常用的自定义函数整理
2010/12/02 PHP
在smarty中调用php内置函数的方法
2013/02/07 PHP
php中数字、字符与对象判断函数用法实例
2014/11/26 PHP
php集成套件服务器xampp安装使用教程(适合第一次玩PHP的新手)
2015/06/03 PHP
thinkPHP中多维数组的遍历方法
2016/01/09 PHP
简单谈谈php浮点数精确运算
2016/03/10 PHP
php preg_match的匹配不同国家语言实例
2016/12/29 PHP
PHP中phar包的使用教程
2017/06/14 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
Javascript 异步加载详解(浏览器在javascript的加载方式)
2012/05/20 Javascript
ANT 压缩(去掉空格/注释)JS文件可提高js运行速度
2013/04/15 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
javascript的数组和常用函数详解
2014/05/09 Javascript
javascript事件委托的用法及其好处简析
2016/04/04 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
基于JS实现类似支付宝支付密码输入框
2016/09/02 Javascript
JavaScript仿百度图片浏览效果
2016/11/23 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
2018/08/22 Javascript
electron + vue项目实现打印小票功能及实现代码
2018/11/25 Javascript
jquery实现垂直无限轮播的方法分析
2019/07/16 jQuery
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
使用Python生成随机密码的示例分享
2016/02/18 Python
浅谈python中的__init__、__new__和__call__方法
2017/07/18 Python
python中使用正则表达式的连接符示例代码
2017/10/10 Python
python之Flask实现简单登录功能的示例代码
2018/12/24 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
2020/06/15 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
python 制作本地应用搜索工具
2021/02/27 Python
孤独星球出版物:Lonely Planet Publications
2018/03/17 全球购物
比较基础的php面试题及答案-填空题
2014/04/26 面试题
土木工程应届生自荐信
2013/09/24 职场文书
现金出纳岗位职责
2014/03/15 职场文书
捐资助学感谢信
2015/01/21 职场文书
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技