BucketSort

桶排序(Bucket sort)或箱排序(Bin sort),是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是 鸽巢排序 的一种归纳结果。

基本原理

桶排序也叫箱排序。工作原理是将数组元素映射到有限数量个桶里,利用计数排序可以定位桶的边界,每个桶再各自进行桶内排序(使用其它排序算法或以递归方式继续使用桶排序)。

算法步骤

  • 设置固定数量的空桶
  • 把数据放到对应的桶中
  • 对每个不为空的桶中数据进行排序
  • 拼接不为空的桶中数据,得到结果

动画演示

BucketSort

参考实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import Sort.internal.Comparison.InsertSort;

import java.util.Arrays;

/**
* @author wylu
*/
public class BucketSort {

//桶的个数
private static int m = 5;

//创建桶
private static int[][] buildBucket(int[] arr, int min, int gap) {
int[][] buckets = new int[m][];
//每个桶的元素个数
int[] counts = new int[m];
for (int e : arr) counts[(e - min) / gap]++;
for (int i = 0; i < m; i++) {
buckets[i] = new int[counts[i]];
}
return buckets;
}

public static void sort(int[] arr) {
int min = arr[0], max = arr[0];
for (int e : arr) {
if (e < min) min = e;
if (e > max) max = e;
}

//桶的大小
int gap = (max - min) / m + 1;
int[][] buckets = buildBucket(arr, min, gap);

//将每个元素映射到相应的桶中
int[] cur = new int[m];
for (int e : arr) {
//桶编号
int id = (e - min) / gap;
buckets[id][cur[id]++] = e;
}

//进行桶内排序
int idx = 0;
for (int[] bucket : buckets) {
if (bucket.length == 0) continue;
InsertSort.sort(bucket);
for (int e : bucket) {
arr[idx++] = e;
}
}
}

public static void main(String[] args) {
int[] arr = {5, 3, 4, 7, 2, 4, 3, 4, 7};
BucketSort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}

复杂度分析

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性
桶排序 \(O(n+m)\) \(O(n)\) \(O(n^2)\) \(O(n+m)\) Out-place 稳定

References

https://en.wikipedia.org/wiki/Bucket_sort

https://youliao.163yun.com/api-server/rss/xiaomi/item/IN2WDOMKAWVNTZV.html?ref=browser_news&s=mb&cp=cn-netease-youliao-browser&docid=44797c69e120935b2c4790d933d02a9b&itemtype=news&cateCode=rec&category=%E7%A7%91%E6%8A%80