代码如下

<?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. zabbix自定义添加主机

    1.安装zabbix-agent [root@web01 ~]# rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/3.4/rhe ...

  2. UserTokenManager JwtHelper

    package org.linlinjava.litemall.wx.service; import org.linlinjava.litemall.wx.util.JwtHelper; /** * ...

  3. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis) 的学习实践总结【第六天】

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  4. 再来看看Java的新特性——Stream流

    半年前开始试着使用Java的新特性,给我印象最深的就是Stream流和Optional.其中Stream提高了看法效率,让代码看起来十分清爽. 为什么要使用流? 摘要中已经说明了,为了提高开发效率.流 ...

  5. 【网络流+贪心】Homework

    题目描述 Taro is a student of Ibaraki College of Prominent Computing. In this semester, he takes two cou ...

  6. 我是如何在四年时间里,从厨师转行为 Serverless 应用开发者

    ▎本文系译文,我的软件开发入行经历非常有趣 -- 我一开始其实是厨师. 作者:KieranMcCarthy 译者:Aceyclee 我在高中时就喜欢烹饪和烘焙,用不同食材的搭配去做出美味的食物,就像个 ...

  7. Docker系列六: 使用Docker官方公共仓库和私有仓库

    使用公共仓库 登陆官方网站:https://hub.docker.com/   注册账号和密码 在Docker hub中创建一个资源,  create  respositories,   创建后会提示 ...

  8. python学习笔记(22)-os文件操作模块

    疑问: 如果打开操作一个文件,是用绝对路径好还是相对路径好? os模块,在lib下面,可以直接引入的,直接使用import. 一.新建一个目录,新建一个文件夹 import os #新建一个文件夹 o ...

  9. phpcms添加图片投票

    1phpcms加入投票选项的图片上传功能,从我的文件下载,然后到phpcms目录下直接覆盖即可. 当然这边出现了一个bug,修改投票选项不能修改的bug,只需要修改vote_option_class. ...

  10. JSON — Java与JSON数据互转

    转换时Bean所要求的: 被转换的Bean必需是public的. Bean被转换的属性一定要有对应的get方法,且一定要是public的. Bean中不能用引用自身的this的属性,否则运行时出现et ...