原理
计数排序适用于特定条件下的排序:1. 排序内容在一定范围 k 内,如 1-1000 之间的整数;2. 并且元素之间有固定的步长。
对于满足上述条件的数据可以将排序内容先循环一遍,建立一个键值对映射,键为需要排序的元素,值为此元素出现的个数,最后将映射中的内容输出为有序数组即可。
步骤
- 首先循环原数组,以元素为键,出现的次数为值,存入到映射中。
- 接着循环 k 次,从映射中依次取出元素放入数组,排序完成。
此图来自:runoob.com 计数排序
代码
declare(strict_types=1); | |
class Algorithm | |
{ | |
public function countingSort(array $s, int $max, int $min = 0, int $gap = 1): array{ | |
$map = []; | |
foreach ($s as $i) { | |
$map[$i] = ($map[$i] ?? 0) + 1; | |
} | |
$arr = []; | |
for ($i = $min; $i <= $max; $i += $gap) { | |
while (!empty($map[$i])) { | |
$arr[] = $i; | |
$map[$i]--; | |
} | |
} | |
return $arr; | |
} | |
} |
时间复杂度
两个循环:O(n+k)
最好情况(数组没有重复的元素):O(n+k)
最坏情况(数组中全是重复元素):O(2n+k)
空间复杂度
需要新建一个映射数组:O(k)