title: PHP常用数组排序算法
tags: [PHP,数组,排序,算法]
这几天写到的代码中,用到了许多对数组排序的处理,于是便整理了一下。
原文博客:煜儿博客
一. 冒泡排序
<?php
/*
* 思路:
* 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
* 走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
*/
function BubbleSort($arr){
$count = count($arr);
$temp = 0;
//外层控制排序轮次
for($i=0; $i<$count-1; $i++){
//内层控制每轮比较次数
for($j=0; $j< $count-1-$i; $j++){
if($arr[$j] > $arr[$j+1]){
$temp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $temp;
}
}
}
return $arr;
}
$arr= array(6,3,8,2,9,1);
$res = BubbleSort($arr);
var_dump($res);
二. 选择排序
/*
* 思路:
* 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
* 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)
*/
function selectSort($array){
$temp = 0;
for($i = 0;$i < count($array) - 1;$i++){
$minVal = $array[$i]; //假设$i就是最小值
$minValIndex = $i;
for($j = $i+1;$j < count($array);$j++){
if($minVal > $array[$j]){ //从小到大排列
$minVal = $array[$j]; //找最小值
$minValIndex = $j;
}
}
$temp = $array[$i];
$array[$i] = $array[$minValIndex];
$array[$minValIndex] = $temp;
}
}
$arr= array(6,3,8,2,9,1);
$res = selectSort($arr);
var_dump($res);
三. 插入排序
/*
* 思路:
* 每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
* 算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
* */
function insertSort($array){ //从小到大排列
//先默认$array[0],已经有序,是有序表
for($i = 1;$i < count($array);$i++){
$insertVal = $array[$i]; //$insertVal是准备插入的数
$insertIndex = $i - 1; //有序表中准备比较的数的下标
while($insertIndex >= 0 && $insertVal < $array[$insertIndex]){
$array[$insertIndex + 1] = $array[$insertIndex]; //将数组往后挪
$insertIndex--; //将下标往前挪,准备与前一个进行比较
}
if($insertIndex + 1 !== $i){
$array[$insertIndex + 1] = $insertVal;
}
}
}
$arr= array(6,3,8,2,9,1);
$res = insertSort($arr);
var_dump($res);
四. 快速排序
/*
* 思路:
* 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
* 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
* */
function quickSort($array){
if(!isset($array[1])) return $array;
$mid = $array[0]; //获取一个用于分割的关键字,一般是首个元素
$leftArray = array();
$rightArray = array();
foreach($array as $v){
if($v > $mid)
$rightArray[] = $v; //把比$mid大的数放到一个数组里
if($v < $mid)
$leftArray[] = $v; //把比$mid小的数放到另一个数组里
}
$leftArray = quickSort($leftArray); //把比较小的数组再一次进行分割
$leftArray[] = $mid; //把分割的元素加到小的数组后面,不能忘了它哦
$rightArray = quickSort($rightArray); //把比较大的数组再一次进行分割
return array_merge($leftArray,$rightArray); //组合两个结果
}
$arr= array(6,3,8,2,9,1);
$res = quickSor($arr);
var_dump($res);
这是几种常用的对数组排序的算法,但具体要用哪一种呢?其实选择还是要看是否符合自己的需求,于是我对这四种排序进行了运行时间的比较:
比较的基数是:生成3000个元素的随机数组
$a = array_rand(range(1,10000), 3000);
然后将其打乱:
shuffle($a);
进行计算(计算只列举一次,其他相同)
$t1 = microtime(true);
BubbleSort($a);
$t2 = microtime(true);
echo "冒泡排序用时:".(($t2-$t1)*1000).'ms'."\n";
经过对比发现:
- 冒泡排序 857.98192024231ms
- 选择排序 903.74493598938ms
- 插入排序 296.8270778656ms
- 快速排序 15.607833862305ms
而PHP内置的sort函数排序则用时:
- sort排序 0.95200538635254ms
此时,这些排序的运行时效就很直观了。
网友评论