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 相关文章推荐
漂亮但不安全的CTB
Oct 09 PHP
网络资源
Oct 09 PHP
php 智能404跳转代码,适合换域名没改变目录的网站
Jun 04 PHP
table标签的结构与合并单元格的实现方法
Jul 24 PHP
PHP header()函数常用方法总结
Apr 11 PHP
PHP curl实现抓取302跳转后页面的示例
Jul 04 PHP
PHP导出Excel实例讲解
Jan 24 PHP
将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
Mar 03 PHP
PHP实现的随机IP函数【国内IP段】
Jul 20 PHP
使用Codeigniter重写insert的方法(推荐)
Mar 23 PHP
PHP模糊查询技术实例分析【附源码下载】
Mar 07 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
May 14 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生成局部唯一识别码LUID的代码
2012/10/06 PHP
PHP缓存工具XCache安装与使用方法详解
2018/04/09 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
juqery 学习之三 选择器 子元素与表单
2010/11/25 Javascript
js 完美图片新闻轮转效果,腾讯大粤网首页图片轮转改造而来
2011/11/21 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
浅析JavaScript动画
2015/06/10 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
2015/08/18 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
jquery 实现滚动条下拉时无限加载的简单实例
2016/06/01 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
JavaScript中浅讲ajax图文详解
2016/11/11 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
Angular2的管道Pipe的使用方法
2017/11/07 Javascript
angular5 httpclient的示例实战
2018/03/12 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
2018/07/30 Javascript
js滚轮事件 js自定义滚动条的实现
2020/01/18 Javascript
js+canvas绘制图形验证码
2020/09/21 Javascript
vue中是怎样监听数组变化的
2020/10/24 Javascript
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
Python简单实现网页内容抓取功能示例
2018/06/07 Python
使用python对文件中的数值进行累加的实例
2018/11/28 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
python实现简单成绩录入系统
2019/09/19 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
浅谈Python访问MySQL的正确姿势
2020/01/07 Python
python算的上脚本语言吗
2020/06/22 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
什么是跨站脚本攻击
2014/12/11 面试题
你懂得怎么写自荐信吗?
2013/12/27 职场文书
老师对学生的评语
2014/04/18 职场文书
幼儿园新生开学寄语
2015/05/27 职场文书
Mysql中一千万条数据怎么快速查询
2021/12/06 MySQL