用PHP实现的快速排序算法(支持记录原始数组下标)
代码如下
<?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实现的快速排序算法(支持记录原始数组下标)的更多相关文章
- PHP 快速排序算法详解
备注:下面转载的快速排序算法有bug,数组中重复值会被删除,修改后如下: function quickSort($arr){ //递归出口 if(!isset($arr[1])){ return $a ...
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. ...
- C#算法知识点记录
针对算法的知识点进行记录 简易桶排序 首先看一个简易桶排序,有一串数字,进行从大到小排列.数字间隔不大,使用一维数组来当作桶,进行插入排序. static void Main(string[] arg ...
- 快速排序算法(Java)
快速排序算法的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另外一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. class Parti ...
- 快速排序算法(C#实现)
想到了快速排序,于是自己就用C#实现了快速排序的算法: 快速排序的基本思想:分治法,即,分解,求解,组合 . 分解:在 无序区R[low..high]中任选一个记录作为基准(通常选第一个记录,并记为k ...
- 排序系列 之 快速排序算法 —— Java实现
基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变 ...
- 数据结构65:快速排序算法(QSort,快排)
上节介绍了如何使用起泡排序的思想对无序表中的记录按照一定的规则进行排序,本节再介绍一种排序算法——快速排序算法(Quick Sort). C语言中自带函数库中就有快速排序——qsort函数 ,包含在 ...
- AJPFX实践 java实现快速排序算法
快速排序算法使用的分治法策略来把一个序列分为两个子序列来实现排序的思路: 1.从数列中挑出一个元素,称为“基准“2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面 ...
- 排序算法-Java实现快速排序算法
随机推荐
- linux中ftp中文名乱码问题
问题触发环境 1. java中使用org.apache.commons.net.ftp.FTPClient包 2. 通过chrome浏览器的file标签上传文件 3. 在windows上部署的File ...
- F - Fraction Formula Gym - 102307F
Mr. Potato Head has been promoted and now is a math professor at the UNAL. For his first course he i ...
- Iterator接口(迭代器)的使用
Iterator接口(迭代器) 前言 在程序开发中,经常需要遍历集合中的所有元素.针对这种需求,JDK专门提供了一个接口java.util.Iterator.Iterator接口也是Java集合中的一 ...
- 遥测数据导出sql
SELECT (select codename from CD_BGStation where CodeValue=StationCode)as 监测点位,case when [DETECTIONST ...
- Android之布局LinearLayout
1.weight属性用法 主要用于view对象屏幕适配比例 如下图,左边是等比例,右边是1:2比例 实现代码: <LinearLayout xmlns:android="http:// ...
- kubernetes flannel 网卡绑定错误,故障排查
kubernetes 新加了个node,状态Ready,但调度过去的任务,都执行异常 查看异常节点日志 `Error adding net work: open run/flannel/subnet. ...
- 《C 程序设计语言》练习1-4
#include<stdio.h> /*当celsius=0,1,...,100时,打印摄氏温度与华氏温度对照表; 浮点数版本*/ main () { float fahr,celsius ...
- PostgreSQL中实现更新默认值(二)
今天我们用表继承+触发器的方案,来实现表中的更新默认值.这也许是PostgreSQL里最佳的解决方案. 一. 创建一张表,作为父表 create table basic_update( t_updat ...
- JavaScript 的DOM操作及实例
一.Windows对象操作 (1).用代码打开窗口:window.open("第一部分","第二部分","第三部分","第四部分& ...
- python与正则不得不说的故事
今日所得 正则表达式 re模块 正则表达式:字符 元字符 匹配内容 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹 ...