php实现快速排序的三种方法分享


Posted in PHP onMarch 12, 2014

写了三种php快速排示例,第一种效率低但最简单最容易理解,第二个是算法导论上提供的单向一次遍历找中值方法,第三种是双向遍历找中值经典快排算法。三组算法实现和比较如下:

方法一:该方法比较直观,但损失了大量的空间为代价,使用了效率较低的merge函数。在三种方法中效率最低。最坏情况下算法退化为(O(n*n))

function quick_sort($array) {
 if(count($array) <= 1) return $array;
 $key = $array[0];
 $rightArray = array();
 $leftArray = array();
 for($i = 1; $i < count($array); $i++) {
           if($array[$i] >= $key) {
  $rightArray[] = $array[$i];
    } else {
  $leftArray[] = $array[$i];
    }
 }
 $leftArray = quick_sort($leftArray);
 $rightArray = quick_sort($rightArray);
 return array_merge($leftArray, array($key), $rightArray);
}

方法二:该算法来自算法导论,叫作Nico Lomuto方法(感兴趣goole上有详细说明)使用最经典的单方向一次遍历找到中值。
但这种算法在最坏情况下(例如值相同的数组,需要n-1次划分,每一次划分需要O(n) 时间去掉一个元素)最坏情况下为O(n*n)

function quick_sort(&$array, $start, $end) {
    if ($start >= $end) return;
    $mid = $start;
    for ($i = $start + 1; $i <= $end; $i++) {
 if ($array[$i] < $array[$mid]) {
     $mid++;
     $tmp = $array[$i];
     $array[$i] = $array[$mid];
     $array[$mid] = $tmp;
 }
    }
    $tmp = $array[$start];
    $array[$start] = $array[$mid];
    $array[$mid] = $tmp;
    quick_sort($array, $start, $mid - 1);
    quick_sort($array, $mid + 1, $end);
}

方法三:该方法基本上是教科书式的常见写法,首先从左向右遍历小于中间元素的跳过,同时从右向左遍历遇到大的元素跳过,然后

如果没有交叉着交换两边值,继续循环,直到找到中间点。注意该方法在处理相同元素的时候,仍旧交换,这样在最坏情况下也有O(nlogn)

效率。但下面的函数中,如果将$array[$right] > $key 改成 $array[$right] >=$key 或将 $array[$left] < $key改成$array[$left] <= $key则最坏

情况不但会堕落为O(n*n).而且除了每次比较的消耗外,还会产生n次交互的额外开销。该题还有另外两个考点,针对死记硬背的同学:

1:中间的两个while可否互换。当然不能互换,因为对于快盘需要一个额外的空间保存初始的左值,这样左右互换的时候,先用右边覆盖已经保存

为中值的左值,否则会出现问题。见这句$array[$left] = $array[$right];

2:$array[$right] = $key; 该语句含义可否省略。该句不能省略,大家可以考虑一个极端情况比如两个值的排序(5,2),逐步看下就明白了。

function quick_sort_swap(&$array, $start, $end) {
 if($end <= $start) return;
 $key = $array[$start];
 $left = $start;
 $right = $end;
 while($left < $right) {
  while($left < $right && $array[$right] > $key)
   $right--;
  $array[$left] = $array[$right];
  while($left < $right && $array[$left] < $key)
   $left++;
  $array[$right] = $array[$left];
 }
 $array[$right] = $key;
 quick_sort_swap(&$array, $start, $right - 1);
 quick_sort_swap(&$array, $right+1, $end);
}
PHP 相关文章推荐
层叠菜单的动态生成
Oct 09 PHP
PHP常用开发函数解析之数组篇[未完结]
Jul 30 PHP
php+ajax做仿百度搜索下拉自动提示框(有实例)
Aug 21 PHP
php删除文件夹及其文件夹下所有文件的函数代码
Jan 23 PHP
php将gd生成的图片缓存到memcache的小例子
Jun 05 PHP
php实现文件下载(支持中文文名)
Dec 04 PHP
ThinkPHP的模版中调用session数据的方法
Jul 01 PHP
PHP实现QQ空间自动回复说说的方法
Dec 02 PHP
Yii2使用swiftmailer发送邮件的方法
May 03 PHP
PHP简单实现合并2个数字键数组值的方法
May 30 PHP
Laravel实现短信注册的示例代码
May 29 PHP
PHP+redis实现的悲观锁机制示例
Jun 12 PHP
php二分查找二种实现示例
Mar 12 #PHP
php遍历文件夹和文件列表示例分享
Mar 11 #PHP
php获取文件夹路径内的图片以及分页显示示例
Mar 11 #PHP
php上传图片存入数据库示例分享
Mar 11 #PHP
php使用反射插入对象示例分享
Mar 11 #PHP
php数组编码转换示例详解
Mar 11 #PHP
使用Discuz关键词服务器实现PHP中文分词
Mar 11 #PHP
You might like
php正则
2006/07/07 PHP
php中实现记住密码下次自动登录的例子
2014/11/06 PHP
PHP中的事务使用实例
2015/05/26 PHP
PHP微信开发之文本自动回复
2016/06/23 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
PHP+Oracle本地开发环境搭建方法详解
2019/04/01 PHP
彪哥1.1(智能表格)提供下载
2006/09/07 Javascript
如何在Mozilla Gecko 用Javascript加载XSL
2007/01/09 Javascript
Javascript获取HTML静态页面参数传递值示例
2013/08/18 Javascript
常用的jQuery前端技巧收集
2014/12/24 Javascript
JS实现文字掉落效果的方法
2015/05/06 Javascript
JS绘制生成花瓣效果的方法
2015/08/05 Javascript
jQuery实现宽屏图片轮播实例教程
2015/11/24 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
Angular使用Md5加密的解决方法
2017/09/16 Javascript
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变rgba的a值实现)
2019/01/24 Javascript
微信小程序上传图片到php服务器的方法
2019/05/23 Javascript
axios实现文件上传并获取进度
2020/03/25 Javascript
原生js实现二级联动菜单
2019/11/27 Javascript
利用Python中的输入和输出功能进行读取和写入的教程
2015/04/14 Python
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
Python的语言类型(详解)
2017/06/24 Python
利用Python破解斗地主残局详解
2017/06/30 Python
详解python里使用正则表达式的分组命名方式
2017/10/24 Python
关于反爬虫的一些简单总结
2017/12/13 Python
详解python中__name__的意义以及作用
2019/08/07 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
Python基于Socket实现简单聊天室
2020/02/17 Python
python自动点赞功能的实现思路
2020/02/26 Python
Python键鼠操作自动化库PyAutoGUI简介(小结)
2020/05/17 Python
Python就将所有的英文单词首字母变成大写
2021/02/12 Python
Linux文件系统类型
2012/09/16 面试题
给病人的慰问信
2015/03/23 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
表彰大会新闻稿
2015/07/17 职场文书