说明:本文是对我的学习冒泡、快速、选择和插入排序的小总结。面试常常问这些东西,虽然不知道为啥老爱问这些,该问的又不问。无论咋样,我的学习MySQL时有关索引就用到快速排序,索引也是以B+Tree数据结构保存的(Innodb存储引擎),因此基本功仍是很重要的嘛。php
我的实验发现,快速排序在这四个排序当中彷佛是最快的,看下图比较直观:面试
看下代码吧:算法
<?php /** * Created by PhpStorm. * User: liuxiang * Date: 16/6/15 * Time: 21:33 */ class QuickSort{ /** * 递归 * * 快速排序过程: * 1.给初始值,$mid=$data[0] * 2.第二个值开始,与$mid比较,小的放在左边,大的放在右边 * 3.递归,直到数组就剩一个值 * * 效率低,还使用了array_merge()方法 * * @param array $data * @return array */ public function arrayQuickSort(array $data) { $count = count($data); if($count <= 1){ return $data; } $mid = $data[0]; $left = $right = []; for($i=1; $i<$count; $i++){ ($data[$i] < $mid) ? $left[] = $data[$i] :$right[]=$data[$i]; } $left = $this->arrayQuickSort($left); $right = $this->arrayQuickSort($right); return array_merge($left, [$mid], $right); } } $arr = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7]; $arr2 = array_rand(range(1, 1000), 500); shuffle($arr2); $quickSort = new QuickSort(); $time1 = microtime(true); //$quickArr = $quickSort->arrayQuickSort($arr); $quickArr = $quickSort->arrayQuickSort($arr2);//11.8780136108ms $time2 = microtime(true); //var_dump($quickArr); echo (($time2 - $time1)*1000).'ms'.PHP_EOL;
实验快速排序,排序随机的500个数只要11ms左右,还挺快。
数组
冒泡排序效率就比较差了,看图比较直观它的原理:数据结构
看代码吧:学习
<?php /** * Created by PhpStorm. * User: liuxiang * Date: 16/6/15 * Time: 21:26 */ class BubbleSort{ /** * 非递归 * * 冒泡排序算法过程: * 1.比较相连两个元素,若是第一个比第二个大,交换位置 * 2.n个数,须要观察n-1次 * 3.每个数number,须要与其他n-1个数比较,但实际只须要排序n-1-$i,如5,4,3,2,1就5通过4=5-1-0次排序4,3,2,1,5,而4只通过3=5-1-1次排序3,2,1,4,5 * 4.直到排序次数走完,一个乱序就可排为升序或降序了 * 平均时间复杂度最优n,最差n^2 */ /** * @param array $data * @return array */ public function arrayBubbleSort(array $data){ $count = count($data); for($i=0; $i<$count; $i++){ for($j=0; $j<$count-1-$i; $j++){ // for($j=0; $j<$count-1; $j++){//这样也能够,不过多了$i次比较 if($data[$j] > $data[$j+1]){ $this->swap($data[$j], $data[$j+1]); } } } return $data; } /** * 字符串排序也和数组同样,字符串数组形式访问字符 * @param string|string $str * @return string */ public function stringBubbleSort(string $str) { $count = strlen($str); for($i=0; $i<$count; $i++){ for($j=0; $j<$count-1-$i; $j++){ if($str[$j] > $str[$j+1]){ $this->swap($str[$j], $str[$j+1]); } } } return $str; } /** * 交换变量值 * @param $var1 * @param $var2 */ public function swap(&$var1, &$var2) { $tmp = $var1; $var1 = $var2; $var2 = $tmp; } } $arr = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7]; $str = 'SegmentFault'; $arr2 = array_rand(range(1, 1000), 500); shuffle($arr2); $sort = new BubbleSort(); $time1 = microtime(true); //$bubbleArr = $sort->arrayBubbleSort($arr); $bubbleArr = $sort->arrayBubbleSort($arr2);//316.018104553ms $time2 = microtime(true); //var_dump($bubbleArr); echo (($time2 - $time1)*1000).'ms'.PHP_EOL;
实验冒泡排序,排序随机的500个数须要316ms左右,慢的不行。
ui
插入排序我的以为就像是玩扑克,牌桌上n张牌,一张张抓过来,而后新牌根据手上的m张牌依次比较,找到对应位置。看图比较直观:this
看代码吧:spa
<?php /** * Created by PhpStorm. * User: liuxiang * Date: 16/6/23 * Time: 18:14 */ class InsertSort { /** * 插入排序具体算法描述 * 1.从第一个元素开始,该元素能够认为已经被排序 * 2.取出下一个元素,在已经排序的元素序列中从后向前扫描 * 3.若是该元素(已排序)大于新元素,将该元素移到下一位置 * 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 * 5.将新元素插入到该位置后 * 6.重复步骤2~5 * * @param array $data * @return array */ public function arrayInsertSort(array $data) { $count = count($data); for($i=0; $i<$count-1; $i++){ for($j=$i+1; $j>0; $j--){ if($data[$j] > $data[$j-1]){ break; } $this->swap($data[$j-1], $data[$j]); } } return $data; } /** * 交换变量值 * @param $var1 * @param $var2 */ public function swap(&$var1, &$var2) { $tmp = $var1; $var1 = $var2; $var2 = $tmp; } } $arr = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7]; $arr2 = array_rand(range(1, 1000), 500); shuffle($arr2); $insert = new InsertSort(); $time1 = microtime(true); //$insertArr = $insert->arrayInsertSort($arr); $insertArr = $insert->arrayInsertSort($arr2);//315.321922302ms $time2 = microtime(true); //var_dump($insertArr); echo (($time2 - $time1)*1000).'ms'.PHP_EOL;
实验插入排序,排序随机的500个数须要315ms左右,和冒泡排序差很少速度。
3d
选择排序速度还行,看图:
看代码吧:
<?php /** * Created by PhpStorm. * User: liuxiang * Date: 16/6/23 * Time: 17:50 */ class SelectSort { /** * 1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 * 2.再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾 * 3.以此类推,直到全部元素均排序完毕 * * @param array $data * @return array */ public function arraySelectSort(array $data) { $count = count($data); for($i=0; $i<$count - 1; $i++){ $min = $i; for($j=$i+1; $j<$count; $j++){ if($data[$min] > $data[$j]){ $min = $j; } } if($min != $i){ $this->swap($data[$min], $data[$i]); } } return $data; } /** * 交换变量值 * @param $var1 * @param $var2 */ public function swap(&$var1, &$var2) { $tmp = $var1; $var1 = $var2; $var2 = $tmp; } } $arr2 = array_rand(range(1, 1000), 500); shuffle($arr2); $arr = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7]; $select = new SelectSort(); $time1 = microtime(true); //$selectArr = $select->arraySelectSort($arr); $selectArr = $select->arraySelectSort($arr2);//44.0230369568ms $time2 = microtime(true); //var_dump($selectArr); echo (($time2 - $time1)*1000).'ms'.PHP_EOL;
实验选择排序,排序随机的500个数须要44ms左右,速度还行。
总结:排序和查找是永恒主题。扎实下基本功,会继续学习相关排序和查找算法,到时见。