备注:下面转载的快速排序算法有bug,数组中重复值会被删除,修改后如下:

function quickSort($arr){
//递归出口
if(!isset($arr[1])){
return $arr;
}
//第一个弹出
$mid = array_shift($arr);
//把刚才弹出的放到一个数组
$midArray = array($mid);
//定义左右空数组
$leftArray = array();
$rightArray = array();
foreach($arr as $v){
if($v>$mid){
$rightArray[]=$v;
}else{
$leftArray[]=$v;
}
}
//递归调用
return array_merge(quickSort($leftArray),$midArray,quickSort($rightArray));
}

----------------------------------------------这是一条华丽的分割线------------------------------------------

其实快速排序之所以称之快速,就是因为,冒泡排序是每次对比只交换相邻的两个值的位置,这样每个值要移动到它最终的排序结果中所对应的位置,可能需要很多次位置的变化。但是快速排序可在一次划分中,就确定你选定的那个对比值在最终排序好的队列中的位置。

概念:这里借用百度百科的一张图来,非常形象:

快速排序算法是对冒泡算法的一个优化。他的思想是先对数组进行分割, 把大的元素数值放到一个临时数组里,把小的元素数值放到另一个临时数组里(这个分割的点可以是数组中的任意一个元素值,一般用第一个元素,即$array[0]),然后继续把这两个临时数组重复上面拆分,最后把小的数组元素和大的数组元素合并起来。这里用到了递归的思想。

/*
快速排序
*/
function quickSort($array)
{
if(!isset($array[1]))
return $array;
$mid = $array[0]; //获取一个用于分割的关键字,一般是首个元素
$leftArray = array();
$rightArray = array(); foreach($array as $v)
{
if($v > $mid)
$rightArray[] = $v; //把比$mid大的数放到一个数组里
if($v < $mid)
$leftArray[] = $v; //把比$mid小的数放到另一个数组里
} $leftArray = quickSort($leftArray); //把比较小的数组再一次进行分割
$leftArray[] = $mid; //把分割的元素加到小的数组后面,不能忘了它哦 $rightArray = quickSort($rightArray); //把比较大的数组再一次进行分割
return array_merge($leftArray,$rightArray); //组合两个结果
}

与冒泡算法对比

这里我与之前写的冒泡算法实现的排序做了个对比,可以看出这个算法比冒泡算法的效率要高很多。

$a = array_rand(range(1,3000), 1500);  //甚至在冒泡算法超过1600个元素的时候会出现内存不足的提示,但这里为了测出两个之间的差别大小, 就设置成了1500,保证冒泡算法也能执行完毕。
shuffle($a); //获取已经打乱了顺序的数组
$t1 = microtime(true);
quickSort($a); //快速排序
$t2 = microtime(true);
echo (($t2-$t1)*1000).'ms<br/>';
require('./maopao.php'); //这里引用的是我之前写的冒泡算法排序
$t1 = microtime(true);
maoPao($a); //冒泡
$t2 = microtime(true);
echo (($t2-$t1)*1000).'ms';

运行结果:

11.112928390503ms
469.88606452942ms

附:冒泡排序代码

function maoPao($arr){
$num = count($arr);
for($i=0;$i<=$num-1;$i++){
for($j=0;$j<$num-$i-1;$j++){
if($arr[$j]>$arr[$j+1]){
$temp = $arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1]=$temp;
}
}
}
return $arr;
}

PHP 快速排序算法详解的更多相关文章

  1. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  2. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  3. kmp算法详解

    转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...

  4. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  5. [转] KMP算法详解

    转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段.    我们这里说的K ...

  6. 【转】AC算法详解

    原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...

  7. KMP算法详解(转自中学生OI写的。。ORZ!)

    KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...

  8. EM算法详解

    EM算法详解 1 极大似然估计 假设有如图1的X所示的抽取的n个学生某门课程的成绩,又知学生的成绩符合高斯分布f(x|μ,σ2),求学生的成绩最符合哪种高斯分布,即μ和σ2最优值是什么? 图1 学生成 ...

  9. Tarjan算法详解

    Tarjan算法详解 今天偶然发现了这个算法,看了好久,终于明白了一些表层的知识....在这里和大家分享一下... Tarjan算法是一个求解极大强联通子图的算法,相信这些东西大家都在网络上百度过了, ...

随机推荐

  1. 【数据库】SQL经典面试题 - 数据库查询 - 子查询应用二

    上节课我们通过子查询,完成了查询的最高分学生的需求,今天我们来学习子查询的分类,以及通过子查询来完成工作中经常遇到一些个性化需求. 子查询概念: 一个SELECT语句嵌套在另一个SELECT语句中,子 ...

  2. C# XML序列化和反序列化

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  3. c语言学习笔记.链表.

    链表: 链表单个节点的数据结构.链表的实现主要依靠结构体和指针. 头指针(head)指向链表的第一个节点,然后第一个节点中的指针指向下一个节点,然后依次指到最后一个节点,这样就构成了一条链表. str ...

  4. codepage 和 charset

    codepage:简单地说,这是程序用于对字符进行编码的一个表.代码页是服务器的事情. 常见的三种codepage 简体中文 : 936 繁体中文 : 950 UTF-8 : 65001 如果你不想用 ...

  5. MIUI7,Android版本5.0.2,一个程序发送自定义广播,另一个程序没有接收到

    对照<第一行代码——Android>进行学习,第五章中说到广播包的相关知识,前面获取广播等程序例程都可以跑的通,但是在5.3.2节中,程序A发送自定义广播,并接收自定义广播,同时程序B也接 ...

  6. Shell-输入密码转换为*

    Code: read -p "请输入使用者都名称:" USER echo -e "请输入使用者密码: \c" while : ;do char=` #这里是反引 ...

  7. ip分片重组 ip_defrag

    在ip_local_deliver中,如果检测到是分片包,则需要进行分片重组: ip_local_deliver |-->ip_is_fragment //判断是否为分片包 |-->ip_ ...

  8. Linux下MySQL/MariaDB Galera集群搭建过程【转】

    MariaDB介绍 MariaDB是开源社区维护的一个MySQL分支,由MySQL的创始人Michael Widenius主导开发,采用GPL授权许可证. MariaDB的目的是完全兼容MySQL,包 ...

  9. SQL 存储过程分页

    CREATE PROC p_Team_GetTemaList @pageindex INT , @pagesize INT , @keywords VARCHAR(200) , --模糊查询 名称 标 ...

  10. word文档下划线无法显示的解决方法

    在编辑文档的时候经常会遇到下划线无法显示的情况,如图: 如果遇到不能在姓名后面加下划线的情况,我们该怎么做? 请看下面的图解: 1.首先点击左上角的office图标 2.点击右下角“word选项” 3 ...