php实现常见排序,插入排序、希尔排序、直接选择、堆排序、冒泡排序、快速排序、归并排序、基数排序
常见排序
- 常见排序有插入排序、希尔排序、直接选择、堆排序、冒泡排序、快速排序、归并排序、基数排序
- 按照稳定情况:
- 稳定:插入排序、冒泡排序、归并排序、基数排序
- 不稳定:希尔排序、直接选择、堆排序、快速排序
实现
1. 冒泡排序
/**
* 冒泡排序
*/
function bubbleSort (){
$arr = [5, 1, 3, 4, 2];
$len = count($arr);
//循环控制冒泡的轮数
for ($i = 0; $i < $len - 1; $i++) {
for ($j = 0; $j < $len - $i - 1; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
$temp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $temp;
}
}
}
var_dump($arr); # [1, 2, 3, 4, 5]
}
2. 选择排序
- 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,
-
然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。
function selectSort(){ $arr = [5, 1, 3, 4, 2]; $len = count($arr); # 从待匹配区选择最小的放入已排序的 $i=0开始 for ($i = 0; $i < $len; $i++) { $min = $i; for ($j = $i + 1; $j < $len; $j++) { if ($arr[$min] > $arr[$j]) { $min = $j; } } if ($min != $i) { $tmp = $arr[$i]; $arr[$i] = $arr[$min]; $arr[$min] = $tmp; } } var_dump($arr); # [1, 2, 3, 4, 5] }
3. 插入排序
-
它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。
function insertSort(){ $arr = [5, 1, 3, 4, 2]; $len = count($arr); # 待排序区拿出一个插入到已排序区 for ($i = 0; $i < $len - 1; $i++) { $key = $arr[$i + 1]; for ($j = $i; $j >= 0; $j--) { if ($arr[$j] > $key) { $arr[$j + 1] = $arr[$j]; } else { break; } } $arr[$j + 1] = $key; } var_dump($arr); # [1, 2, 3, 4, 5] }
4. 快速排序
- 基本思想:
- 先从数列中取出一个数作为基准数。
- 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 再对左右区间重复第二步,直到各区间只有一个数。
- 总结:
- 性能方面其实是看php版本,比如我用php 8.1测的结果,随机生成1w个数,然后分别调用两个排序各1000次,得出的结果是,执行的时间差1s不到
-
递归
function quickSortByRecursion($arr) { $len = count($arr); if ($len <= 1) { return $arr; } $left = $right = []; //使用for循环进行遍历,把第一个元素当做比较的对象 for ($i = 1; $i<$len; $i++) { if ($arr[$i] < $arr[0]) { $left[] = $arr[$i]; } else { $right[] = $arr[$i]; } } //递归调用 $left = quickSortByRecursion($left); $right = quickSortByRecursion($right); //将所有的结果合并 return array_merge($left, [$arr[0]], $right); }
-
压栈
function quickSortByStack($arr) { // 用stack栈来存储左中右数据 $stack = [$arr]; $sort = []; while (!empty($stack)) { $tmpArr = array_pop($stack); $size = count($tmpArr); if ($size <= 1) { if ($size == 1) { $sort[] = $tmpArr[0]; } continue; } $mid = $tmpArr[0]; $left = []; $right = []; for ($i=1;$i<$size;$i++) { if ($tmpArr[$i] > $mid) { $right[] = $tmpArr[$i]; } else { $left[] = $tmpArr[$i]; } } $stack[] = $right; $stack[] = [$mid]; $stack[] = $left; } return $sort; }
- 希尔排序
- 是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止
function shellSort() { $arr = [5, 1, 7, 8, 3, 4, 6, 2]; $len = count($arr); $diff = (int) floor($len / 2); # 需要分成几组 for (; $diff > 0; $diff = (int) floor($diff / 2)) { # 需要几次分组 for ($i = 0; $i < $diff; $i++) { # 每个分组排序 for ($j = $i; $j < $len && $j + $diff < $len; $j++) { if ($arr[$j] > $arr[$j + $diff]) { $tmp = $arr[$j + $diff]; $arr[$j + $diff] = $arr[$j]; $arr[$j] = $tmp; } } } } var_dump($arr); # [1,2,3,4,5,6,7,8] }