用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实现快速排序算法
		
 
随机推荐
- day50-线程-定时器
			
#1.定时器: from threading import Timer def func(): print('定时器') t = Timer(1,func) #定时一秒,开启func线程. t.sta ...
 - GIL全局解释器锁-死锁与递归锁-信号量-event事件
			
一.全局解释器锁GIL: 官方的解释:掌握概念为主 """ In CPython, the global interpreter lock, or GIL, is a m ...
 - AI大火之下智能手机行业能适应这一风口吗?
			
今年智能手机行业的变化,实在是让人摸不到头脑.一方面是智能手机厂商依然在拿出各种具有噱头的产品,仿佛整个市场还依然热火朝天.但在另一方面,智能手机出货量却出现大幅下滑.据中国信息通信研究院发布的数据显 ...
 - 关于Tarjan的一些问题
			
$Q:$为什么tarjan求强连通分量要记录点是否在栈内,而求双连通分量不用? $A:$在有向图中存在横叉边,而无向图中不存在: $Q:$为什么用子搜索树中的$low[v]$来更新$low[k]$,而 ...
 - ClipboardMonitor的下载和使用
			
本工具可以实时监视剪贴板的变化,可以用于32位和64位的Excel. 在任务窗格上面输入一个正则表达式,例如(\d+)\-(\d+),按下Enter确认. 然后在其他地方,例如浏览器页面或者记事本中复 ...
 - JQ和JS的等价代码
			
JQ与JS等价代码 选择器 //jquery var els = $(".el"); //原生方法 var els = document.querySelectorAll(&q ...
 - s01字符串---蓝桥杯
			
问题描述 s01串初始为"0" 按以下方式变换 0变1,1变01 输入格式 1个整数(0~19) 输出格式 n次变换后s01串 样例输入 3 样例输出 101 数据规模和约定 0~ ...
 - curl查看请求你响应时间
			
[root@localhost ~]# curl -o /dev/null -s -w time_namelookup:%{time_namelookup}"\n"time_con ...
 - Android activity 亮度调整
			
注意点 screenBrightness 取值范围0-1 不是0-255一定要注意 scanForActivity(context) 是根据上下文获取所在的activity如果直接在activity ...
 - [LC] 167. Two Sum II - Input array is sorted
			
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...