桶排序
桶排序(Bucket sort)是一种基于计数的排序算法,工作的原理是将数据分到有限数量的桶子里,然后每个桶再分别排序(可使用别的排序算法进行排序)
- 桶排序概况
- 要求排序内容已知,排序键为数字
- 主要适用于小范围整数数据,且独立均匀分布.
- 计数排序是一种特殊的桶排序
- 桶排序过程
- 计算并设置固定数量的空桶
- 将数据放入对应的桶中
- 对桶中的数据进行排序
- 把每个桶的数据进行合并
- 图解桶
假设已知需要排序的元素集合为 [ 29, 25, 3, 49, 9, 37, 21, 43] , 桶的数量K设置为5, 每个桶的区间跨度S设置为10,如下
0~9 | 10~19 | 20~29 | 30~39 | 40~49 |
将数据依次放入对应的桶中
0~9 | 10~19 | 20~29 | 30~39 | 40~49 |
[3, 9] | [ ] | [29, 25, 21] | [37] | [49, 43] |
对每个桶中的数据进行排序(倾向使用插入排序, 不消耗更多空间,在数值较少情况下常数消耗比较小)
0~9 | 10~19 | 20~29 | 30~39 | 40~49 |
[3, 9] | [ ] | [21, 25, 29] | [37] | [43, 49] |
把所有桶子的数据进行合并: [3, 9, 21, 25, 29, 37, 43, 49] 可得到排序完成的数组.
- 算法实现
//插入排序
function insertion_sort(A){
for(let i=1; i<A.length; i++){
let p = i-1
const x = A[i]
while(p>=0 && A[p]>x){
A[p+1] = A[p]
p--
}
A[p+1] = x
}
}
//桶排序
function bucket_sort(A, k, s){ //A排序数组,k桶子数量,s桶子空间尺度
const buckets = Array.from({length:k}, ()=>[]) //创建桶子
//把元素放入对应桶子
for(let i=0; i<A.length; i++){
//计算需要放入桶子序号
const idx = ~~(A[i]/s)
buckets[idx].push(A[i])
}
//对每个桶子进行排序
for(let i=0; i<buckets.length; i++){
//此处选取插入排序, 空间消耗少,元素少常数时间消耗短
insertion_sort(buckets[i])
}
//把每个桶子数据合并
return [].concat(...buckets)
}