推荐一首歌
- 木小雅《可能否》
非常喜欢前奏
读
第三章《排序算法》
总结
1:快而简单的排序 - 桶排序
桶排序的思想:
在考试之后,老师要把同学们的分数进行排序,比如有 5 个学生,分数为 9,6,5,5,1 写一个排序算法,来进行排序。
方式有很多,这里使用桶排序的思想做排序。
之后我们可以从小到大循环这些桶,在输出每个桶的分数,是不是就很快的完成了排序呢?
什么是桶排序?
桶排序(也叫箱排序),是所有排序算法中最快,最简单的排序。
方法就是我们需要知道排序元素的范围,放置同样数量的桶,放入桶中,按照顺序输出。
桶排序的性能和特点
O(m+n)的时间复杂度。时间是相当快速。[n为元素的个数,m为桶的个数]
但是会耗费大量的空间占用,如果数据跨度过于大,那么空间也可能无法承受。
适用场景
适合分布较均匀,或者数据跨度并不是很大的话,桶排序是相当快速并且简单的。
由于桶排序的局限性,并不适合跨度比较大,或者 m 远远大于 n的排序。
实现方式[PHP]
//设置测试的五个数据 $array = array(5, 3, 5, 2, 8); function bucket($array) { // 入桶-把对应的数字扔到对应的桶里面去 foreach ($array as $arr) { $bucket[$arr]++; } // 出桶-从小到大的循环这些桶,发现桶里面有东西,就扔出来 for ($i = 0; $i <= max($array); $i++) { if (!isset($bucket[$i])) continue; for ($j = 0; $j < $bucket[$i]; $j++) { $new_array[] = $i; } } return $new_array; } var_dump(bucket($array));
2:咕嘟咕嘟的冒泡排序
原理:
小学在操场排队,老师说 “高的站后面,低的站前面”,但是可能我们并不能第一次就找到合适的位置。
很不凑巧,你是班级里面最低的,但是却站在了末尾,这是老师来了,说,你比他低,你站在他前面,这样重复了几十之后,你站在了第一的位置上。
比喻的说,你就像一个水泡一样慢慢浮了上来。
其实这就是冒泡的原理。
冒泡排序的特点和性能
冒泡排序外层需要 n-1 轮的排序,内部还需要 n 轮的排序,所以其中时间复杂度为O(n2);也算是比较高的了。
冒泡的使用场景
多理解其中思想,平常并不会怎么用到,因为其他算法多多少少会比他更好。
面试可能会问吧。
冒泡的实现
// 定义 数组
$array = [43,54,62,21,66,32,78,36,76,39,1];
$count = count($array);
// 最外层定义 n-1 轮的冒泡轮数
for ($i = 1; $i < $count; $i++) {
// 内层循环定义,因为已经冒泡过一次,所以为 $count - 1 次
for ($k = 0; $k < $count - $i; $k++) {
// 交换位置
if ($array[$k] > $array[$k + 1]) {
list($array[$k], $array[$k + 1]) = [$array[$k + 1], $array[$k]];
}
}
}
var_dump($array);
3:最常用的排序,快速排序
- 什么是快速排序?
快速排序是对冒泡的一种改进,基本总结来说,就是通过二分法不断的对数列进行排序。
- 快速排序原理
在对数列进行排序时候,挑选一个基本数[flag][一般是第一个]把大于这个数的放右边,小于的放左边。
之后再不停的递归对数列排序,直到最后一个。
- 为什么说是对冒泡的改进?
在冒泡中,我们要移动一个数,比如最后一个,那就需要比较 n-1 次,同时交换 n-1 次,效率低下。
其实,只要把第一个数字和最后一个数字交换就好了。
也就是这里,是对冒泡的一种改进。
- 快速排序的特点和性能
因为是从冒泡上改进而来,进行跳跃式交换,所以比较和交换次数少了很多,速度也快了很多。
但是,在最不理想的情况下,复杂度和冒泡是一样的 O(n2) .
快速排序基本上被认为在相同数量级中,平均性能最好的。
- 快速排序的适用范围
在 n 并不是很大的时候,使用简单易懂的快速排序是比较好的办法。
- 实现
<?php function quickSort(array $array) { $len = count($array);
// 避免空数组造成无限死循环 if($len <= 1) return $array; $arrleft = array(); $arrright = array(); $flag = $array[0];
// 开始二分 for($i = 1; $i < $len; $i++) { if($array[$i] <= $flag) { $arrleft[] = $array[$i]; }else{ $arrright[] = $array[$i]; } }
// 递归 $arrleft = quickSort($arrleft); $arrright = quickSort($arrright); return array_merge($arrleft, array($flag), $arrright); } $data = array(10, 12, 43, 32, 123, 12, 9); $newarr = quickSort($data); print_r($newarr);