php 常用四种排序 冒泡,选择,插入,快排
Posted babytuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 常用四种排序 冒泡,选择,插入,快排相关的知识,希望对你有一定的参考价值。
---恢复内容开始---
1冒泡排序。 【为描述方便,例子全面为升序排列】
简述:假设数组有10个数字,从左向右。依次比较,如果前者大于后者,则两两交换。每一轮将冒泡一个最大数出来,依次循环,完成排序
流程描述:
-- 第一次 a[0] 与 a[1] 比如果 a[0] > a[1] 则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到 a[8] 与 a[9] 交换。 此轮过后 a[9] 必为 a[0-9] 中的最大值。
第二次(此时 a[9]以是最大值) a[0] 与 a[1] 比如果 a[0] > a[1] 则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到 a[7] 与 a[8] 交换。 此轮过后 a[8] 必为 a[0-8] 中的最大值。
第三次(此时 a[9]以是最大值,a[8]次大) a[0] 与 a[1] 比如果 a[0] > a[1] 则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到 a[6] 与 a[7] 交换。 此轮过后 a[7] 必为 a[0-7] 中的最大值。
-------------- 如此反复,一次冒泡一个最大值出来。
//冒泡排序代码示例
public function bubbleSort($arr){ //冒泡排序
$len = sizeof($arr); for( $i = 0; $i< $len - 1; $i++){ //冒第几个泡 for( $j = 0; $j < $len - $i - 1 ; $j++){ //未冒完泡的依次比较,找出最大值 if( $arr[$j] > $arr[$j+1]){ $arr = swap($arr , $j , $j+1); } } } return $arr; } //将数组的第 i j 位互换。 //后面代码略 public function swap($arr , $i , $j){ // $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; return $arr; }
2选择排序
简述,假设数组有10个数字,从左向右 1 到9 每个与右边的所有数进行比较,找出右侧最小的,并与之替换。
流程描述:
-- 第一次 a[0] 逐个与 a[1] - a[9] 比对,找到最小值,然后 a[0]与a[0-9]中的最小值进行替换。替换后 a[0] 为数组最小值 (如果0 正好是最小,则不替换 )
第二次 此时a[0],以是最小值,进行下一步。a[1] 逐个与 a[2] - a[9] 比对,找到最小值,然后 a[1]与a[1-9]最小的进行替换。
第三次 此时a[0],以是最小值,a[1] 为数组次小值(前两个元素已排好序) a[2] 逐个与 a[3] - a[9] 比对,找到最小值,然后 a[2]与那个a[2-9]最小值的进行替换。
............... 依次循环,完成排序。
//选择排序代码示例
function selectSort($arr){ // $len = sizeof($arr); for( $i = 0; $i< $len - 1; $i++){ //从左向右遍历,每次找出 i 位的最小值.
$minIndex = $i; for( $j = $i+1; $j < $len ; $j++){ //遍历 i 右边的不断的找出最小值。 if( $arr[$minIndex] > $arr[$j]){ $minIndex = $j; } } //位置交换 if( $i != $minIndex){ //把当次最左边的与向右查找的最小值进行替换。 $arr = $this->swap( $arr , $i , $minIndex);; } } return $arr; }
3 快速排序 (重点)
简述:设置一个基数,然后对数组进行左右切割。(左边比基数小,右边大于等于基数) ,然后再对左边数组做上述操作。 最后将左 数组 基数 右数据 进行归并
//快速排序算法 public function quickSort($arr){ $len = sizeof($arr); if( $len <=1 ) return $arr; $base = $arr[0]; //基数 $l_arr = array(); //左边数组 $r_arr = array(); //右边数组 for($i = 1;$i<$len ; $i++){ if( $arr[$i] < $base){ $l_arr[]= $arr[$i]; }else{ $r_arr[]=$arr[$i]; } } $l_arr = quickSort($l_arr); $r_arr = quickSort($r_arr); return array_merge($l_arr , array($base) , $r_arr); }
4 插入排序 (附带介绍,可以略过)
简述,假设数组有10个数字,从数组第二个开始, 每次向左比较【左边已是一个有序数组】依次向左找到自己的位置,一个一个比。
受制于语言能力,写得很饶口。
-- 第一次 a[1] 与 a[0] 比,如果a[1] < a[0] 则 将a[0] 数据移至 a[1] 位 将 a[1] 的值插入到 a[0]位置上。
-- 第二次 a[2] (待插入值) 与 a[0] , a[1] (已经有序) 如果a[2](待插入值) > a[1] 则 a[2] (待插入值) 不动。 如果小于a[1] 则 将原 a[1] 数值移到 a[2] 中,a[2](待插入值) 的值放入到 a[1]中。 再与 a[0] 比,如果大于 a[0] 则 a[0]值放入到 a[1] 中。
public function insertSort($arr){ $len = sizeof($arr); for( $i = 1; $i< $len ; $i++){ $temp = $arr[$i]; for( $j = $i-1; $j>=0; $j--){ //针对一个有序数据,依次找插入位 if($temp < $arr[$j]){ //逐个插入。 $arr[$j+1] = $arr[$j]; $arr[$j] = $temp; }else{ break; } } } return $arr; }
写在最后:要对大量数据,有量级的概念。 快排的复杂度是 O( N log N) ,冒泡排序是 O(N平方)
仅以1万个数为例。 快排复杂度是 10000 * Log2 10000 约为 13* 万 ,冒泡则是 1亿。 相差约800倍性能。
如果是10万个 快排则是 10万 * log2 100000 约为 170万 而冒泡则是100亿。 瞬间差出约7000 位。
而10万条数据,在真实场景下,真的不多。
如果说感受不明显,就跑跑代码体验下。
/**性能调试。*/ function bench_profile($starttime , $flag = ‘‘){ $endtime = explode(‘ ‘,microtime()); $thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]); $thistime = round($thistime,3); return $flag."-bench:".$thistime." sec"; } $start_time = explode(‘ ‘,microtime()); echo bench_profile($start_time)."<br/>"; $arr = []; for($i=0;$i<10000;$i++){ $arr[]= rand(1,100000); } $arr_insert = quickSort($arr); echo bench_profile($start_time); //1w条跑完时间 -bench:0.053 sec 冒泡算法。 约 45 秒 //10w条跑完时间 -bench:0.77 sec 冒泡算法 约 一个半小时。 //100万条,跑完时间 16秒。 这时需要放开内存限制 ini_set("memory_limit",-1) 。 这时还用冒泡算法。 明天再来看结果。
以上是关于php 常用四种排序 冒泡,选择,插入,快排的主要内容,如果未能解决你的问题,请参考以下文章