代码如下

<?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. mysql字段修改脚本

    -- help_text:帮助说明 -- help_content -- raw USE pro_seal_chip_sell_portal_v1; -- 表修改ALTER TABLE `help_t ...

  2. A brief introduction to complex analysis

    \(\underline{Def:}\)A func \(U(\subset \mathbb{C}) \stackrel{f}\longrightarrow \mathbb{C}\)is (compl ...

  3. regex(python)

    正则表达式 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/7/26 16:39 # @Author : jackendoff ...

  4. vim 复制 单个 单词: 移动光标到单词词首,快速摁 yw

    vim 复制 单个 单词:   移动光标到单词词首,快速摁 yw

  5. php对比二个不同的二维数组

    $diff_data = array_filter($data1, function($v) use ($data2) { return ! in_array($v, $data2);});

  6. [LC] 314. Binary Tree Vertical Order Traversal

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...

  7. 一文带你了解BOM基本知识

    1.1. BOM和DOM的区别DOM就是一套操作HTML标签的API(接口/方法/属性) BOM就是一套操作浏览器的API(接口/方法/属性) 1.2. BOM中常见的对象window: 代表整个浏览 ...

  8. [原]调试实战——使用windbg调试excel启动时死锁

    原调试debugwindbg死锁deadlock 前言 这是几年前在项目中遇到的一个死锁问题,在博客园发布过.我对之前的笔记进行了整理重新发布于此. 本文假设小伙伴们知道一些基本概念,比如什么是.du ...

  9. 005.前端开发知识,前端基础CSS(2020-01-14)

    一.CSS权重 权重是可以叠加的,事例如下: div ul li ------> 0,0,0,3 .nav ul li ------> 0,0,1,2 a:hover -----—> ...

  10. Spring @Column的注解详解

    就像@Table注解用来标识实体类与数据表的对应关系类似,@Column注解来标识实体类中属性与数据表中字段的对应关系. 该注解的定义如下: @Target({METHOD, FIELD}) @Ret ...