代码如下

<?php
/**
* 快速排序
*/
define("MAX_LENGTH_INSERT_SORT", 7); class QuickSort {
/**
* 交换数组i和j的值
*/
function swap(&$data=array(), $i, $j) {
$temp = $data[$i];
$data[$i] = $data[$j];
$data[$j] = $temp;
}
/**
* 交换数组data中子表的记录,是枢轴记录到位,并返回其所在位置
* 左边记录都比枢轴小,右边记录都比枢轴大
* @param array $data 待排序数组
* @param int $low 底端下标
* @param int $high 顶端下标
* @return low 枢轴下标位置
*/
function PartitionAsc(&$data=array(), $low=0, $high=0) {
$pivotkey=0;
//计算数组中间元素的下标
$m = $low+($high-$low)/2;
//交换左端和右端数据,保证左端较小
if($data[$low]>$data[$high]) {
$this->swap($data, $low, $high);
}
//交换中间和右端数据,保证中间较小
if($data[$m]>$data[$high]) {
$this->swap($data, $high, $m);
}
//获取中间数据,并将中间数据交换到左边
if($data[$m]>$data[$low]) {
$this->swap($data, $m, $low);
} //用子表的第一个记录作枢轴记录
$pivotkey = $data[$low];
//将枢轴关键字备份到L->r[0]
$data[0] = $pivotkey;
//从表的两端交替地向中间扫描
while($low<$high) {
while ($low<$high && $data[$high]>=$pivotkey) {
$high--;
}
$data[$low] = $data[$high];
while ($low<$high && $data[$low]<=$pivotkey) {
$low++;
}
$data[$high] = $data[$low];
}
$data[$high] = $data[0];
return $low;
}
/**
* 交换数组data中子表的记录,是枢轴记录到位,并返回其所在位置
* 左边记录都比枢轴大,右边记录都比枢轴小
* @param array $data 待排序数组
* @param int $low 底端下标
* @param int $high 顶端下标
* @return low 枢轴下标位置
*/
function PartitionDesc(&$data=array(), $low=0, $high=0) {
$pivotkey=0;
//计算数组中间元素的下标
$m = $low+($high-$low)/2;
//交换左端和右端数据,保证左端较小
if($data[$low][0]<$data[$high][0]) {
$this->swap($data, $low, $high);
}
//交换中间和右端数据,保证中间较小
if($data[$m][0]<$data[$high][0]) {
$this->swap($data, $high, $m);
}
//获取中间数据,并将中间数据交换到左边
if($data[$m][0]<$data[$low][0]) {
$this->swap($data, $m, $low);
} //用子表的第一个记录作枢轴记录
$pivotkey = $data[$low];
//将枢轴关键字备份到L->r[0]
$data[0] = $pivotkey;
//从表的两端交替地向中间扫描
while($low<$high) {
while ($low<$high && $data[$high][0]<=$pivotkey[0]) {
$high--;
}
$data[$low] = $data[$high];
while ($low<$high && $data[$low][0]>=$pivotkey[0]) {
$low++;
}
$data[$high] = $data[$low];
}
$data[$high] = $data[0];
return $low;
}
/**
* 快速排序(升序)
* @param array $data 待排序数组
* @param int $low 底端下标
* @param int $high 顶端下标
* @return void
*/
function QsortAsc(&$data=array(), $low=0, $high=0) {
$pivot=0;
//当high-low大于常数时用快捷排序
if(($high-$low)>MAX_LENGTH_INSERT_SORT) {
while($low<$high) {
//将data一分为二,算出枢轴值pivot
$pivot = $this->PartitionAsc($data, $low, $high);
//对底子表递归排序
$this->QsortAsc($data, $low, $pivot-1);
//尾递归
$low = $pivot+1;
}
} else {
//当high-low小于等于常数时用直接插入排序
$this->InsertSortAsc($data, $low, $high);
}
}
/**
* 快速排序(降序)
* @param array $data 待排序数组
* @param int $low 底端下标
* @param int $high 顶端下标
* @return void
*/
function QsortDesc(&$data=array(), $low=0, $high=0) {
$pivot=0;
//当high-low大于常数时用快捷排序
if(($high-$low)>MAX_LENGTH_INSERT_SORT) {
while($low<$high) {
//将data一分为二,算出枢轴值pivot
$pivot = $this->PartitionDesc($data, $low, $high);
//对底子表递归排序
$this->QsortDesc($data, $low, $pivot-1);
//尾递归
$low = $pivot+1;
}
} else {
//当high-low小于等于常数时用直接插入排序
$this->InsertSortDesc($data, $low, $high);
}
}
/**
* 插入排序(升序)
*/
function InsertSortAsc(&$data=array(), $low=0, $high=0) {
$i=$j=0;
if(0 == $high) {
$length=count($data)-1;
} else {
$length=$high;
}
for($i=$low+1;$i<=$length;$i++) {
if($data[$i][0]<$data[$i-1][0]) {
$data[0]=$data[$i];
for ($j=$i-1; $data[$j][0]>$data[0][0]; $j--) {
if($j<$low) break;
$data[$j+1]=$data[$j];
}
$data[$j+1]=$data[0];
}
}
}
/**
* 插入排序(降序)
*/
function InsertSortDesc(&$data=array(), $low=0, $high=0) {
$i=$j=0;
if(0 == $high) {
$length=count($data)-1;
} else {
$length=$high;
}
for($i=$low+1;$i<=$length;$i++) {
if($data[$i][0]>$data[$i-1][0]) {
$data[0]=$data[$i];
for ($j=$i-1; $data[$j][0]<$data[0][0]; $j--) {
if($j<$low) break;
$data[$j+1]=$data[$j];
}
$data[$j+1]=$data[0];
}
}
}
/**
* 快速排序
* @param array $data 待排序数组
* @param int $type 1升序 2降序 默认升序
* @return void
*/
function Sort($data=array(), $type=1) {
$length = count($data)-1;
if(1==$type) {
$this->QsortAsc($data, 1, $length);
} else if(2==$type) {
$this->QsortDesc($data, 1, $length);
} else {
$this->QsortAsc($data, 1, $length);
}
return $data;
}
}
/********************************************************/ //测试10万数组排序
//测试数组:array(array(排序数据, 原始数组下标),......)
$data = array(array(0,0));
$max_len = 100000;
for($i=1; $i<$max_len; $i++) {
$data[$i] = array(rand(1,$max_len),$i);
} $qs = new QuickSort();
//1升序, 2降序
$qs->Sort($data,2);
$qs->Sort($data,1);

测试结果:10万条数据耗时2.7秒

用PHP实现的快速排序算法(支持记录原始数组下标)的更多相关文章

  1. PHP 快速排序算法详解

    备注:下面转载的快速排序算法有bug,数组中重复值会被删除,修改后如下: function quickSort($arr){ //递归出口 if(!isset($arr[1])){ return $a ...

  2. java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述

    算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. ...

  3. C#算法知识点记录

    针对算法的知识点进行记录 简易桶排序 首先看一个简易桶排序,有一串数字,进行从大到小排列.数字间隔不大,使用一维数组来当作桶,进行插入排序. static void Main(string[] arg ...

  4. 快速排序算法(Java)

    快速排序算法的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另外一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. class Parti ...

  5. 快速排序算法(C#实现)

    想到了快速排序,于是自己就用C#实现了快速排序的算法: 快速排序的基本思想:分治法,即,分解,求解,组合 . 分解:在 无序区R[low..high]中任选一个记录作为基准(通常选第一个记录,并记为k ...

  6. 排序系列 之 快速排序算法 —— Java实现

    基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变 ...

  7. 数据结构65:快速排序算法(QSort,快排)

    上节介绍了如何使用起泡排序的思想对无序表中的记录按照一定的规则进行排序,本节再介绍一种排序算法——快速排序算法(Quick Sort). C语言中自带函数库中就有快速排序——qsort函数 ,包含在 ...

  8. AJPFX实践 java实现快速排序算法

    快速排序算法使用的分治法策略来把一个序列分为两个子序列来实现排序的思路: 1.从数列中挑出一个元素,称为“基准“2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面 ...

  9. 排序算法-Java实现快速排序算法

随机推荐

  1. Docker搭建RabbitMQ(阿里云)

    0 环境 系统环境:centos7 服务器:阿里云 1 正文 1 获取安装RabbitMQ https://hub.docker.com/_/rabbitmq 默认rabbitmq镜像是不带web端管 ...

  2. tensorflow(七)

    一.模型托管工具 TensorFlow Serving TensorFlow Serving支持生产级的服务部署,允许用户快速搭建从模型训练到服务发布的工作流水线. 工作流水线主要由三部分构成 (1) ...

  3. USB Reverse Tether (a dirty solution)

    Tether your android phone to your PC using USB cable could share your 3g Internet connection with PC ...

  4. Maven中settings.xml文件各标签含义

    原文地址:http://www.cnblogs.com/jingmoxukong/p/6050172.html?utm_source=gold_browser_extension settings.x ...

  5. mac环境下创建bash_profile文件并写入内容 更改php环境变量

    1. 启动终端Terminal 2. 进入当前用户的home目录 输入cd ~ 3. 创建.bash_profile 输入touch .bash_profile 4. 编辑.bash_profile文 ...

  6. 一、linux-mysql 运维DBA介绍

    一.DBA数据库管理人员需要在整个架构中解决数据库的压力,前端业务通过扩展,加机器就可以很好的解决,但是存储.数据库就不是很好的可以进行扩展,数据也是分配不均的,所以,1)通过在数据库前面添加Memc ...

  7. 论文翻译——Character-level Convolutional Networks for Text Classification

    论文地址 Abstract Open-text semantic parsers are designed to interpret any statement in natural language ...

  8. 用 Apache Derby 进行 ODBC 编程

    用 Apache Derby 进行 ODBC 编程 https://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0409kar ...

  9. 计算机数制与IPv4

    常用计数:十进制数 1010D.二进制 1010B.十六进制1010H 计算机数制: 数制组成=每一位上的数字*该位的值 IPV4地址一共32bit 人使用点分十进制的方式来进行记忆 IPv6地址一共 ...

  10. Office 365管理员添加自定义域名

    添加自定义域,以便Office 365允许更短.更熟悉的的电子邮件或用户ID用于服务 一.Office 365小型企业版添加自定义域名 1.使用Office 365管理员账户登陆到由世纪互联运营的Of ...