桶排序
算法思想
1.首先根据要排序的最大值和最小值建立桶的个数并编号
2.将数据放入对应的桶中,在依次循环输出
过程
- 待排序数据 [9,3,5,5,8,1,2]
- 找出最大值和最小值max min
- 建立的桶
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 0
[7] => 0
[8] => 0
[9] => 0 - 循环遍历待排序数组,将桶的值++
<?php
date_default_timezone_set('PRC');
function bucketSort($arr){
//待排序桶的最大值和最小值创建桶
$min = min($arr);
$max = max($arr);
//创建桶
$bucket = [];
for($i = $min;$i<=$max;$i++){
$bucket[$i] = 0;
}
//待排数组放入桶中
$count = count($arr);
for($j = 0;$j < $count;$j++){
$bucket[$arr[$j]] ++;
}
//输出结果 以桶为基础循环 查找桶内值的数量循环输出
$result = [];
for($n = $min; $n <=$max;$n ++){
if($bucket[$n] > 0){
for($m =1; $m <=$bucket[$n];$m++){
$result[] = $n;
}
}
}
return $result;
}
$arr = [9,3,5,5,8,1,2];
print_r(bucketSort($arr));
效率分析
- 对于N个待排 M个桶
- 时间复杂度:O(N+C),其中C=N*(logN-logM)
- 空间复杂度:O(M+N)
- 稳定性:稳定排序
不足
- 参与排序的必须是整数
- 数组的最大数和最小保持在一个合理的范围
- 需要额外的存储空间
算法优化
假设有1亿的数据,那么就要创建1亿个桶来存放数据,可以创建不同等级的几个桶来存放不同的数据阶段,然后在分别排序,在进行合并
function bucketSort1($arr1){
$length = count($arr1);
$min = min($arr1);
$max = max($arr1);
//确定桶的个数
$n = ceil(($max - $min) /$length) +1;
//初始化桶
$bucket = [];
for($i =0; $i < $n; $i++){
$bucket[$i] = [];
}
//将每个元素放入对应的桶内
for($j = 0; $j < $length;$j++){
$index = ceil(($arr1[$j] - $min)/$length);
$bucket[$index][] = $arr1[$j];
}
//对每个桶的数据进行排序
$res = [];
for($m = 0;$m < $n;$m++){
sort($bucket[$m]);
$res = array_merge($res,$bucket[$m]);
}
return $res;
}
$arr1 = [12, 31, 85, 7, 41, 34, 10, 96];
bucketSort1($arr1);
应用场景
- 计算数组中整型某个数出现的次数
- 对数据差距不大的整型数据排序是可以的
- 大数据量,具有格律的整数