根据待排序数据元素的数量,选定一定数量的桶将元素均匀分布到各个桶中,对每个桶进行桶内排序(稳定或不稳定取决于具体问题)
排好后再依次将桶中元素取出
时间复杂度 O(n + m)其中n为输入规模,m为桶的个数
为了使桶排序更加高效,我们需要做到这两点:
- 在额外空间充足的情况下,尽量增大桶的数量
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
import java.util.*;
public class Main {
static final int SIZE = 100000; //每个桶的范围大小
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = sc.nextInt();
//找最大最小值
int max = a[0], min = a[0];
for (int i = 1; i < a.length; i++) {
max = Math.max(a[i], max);
min = Math.min(a[i], min);
}
//确定桶的个数
int bs = (max - min) / SIZE + 1;
List<Integer>[] b = new ArrayList[bs];
for (int i = 0; i < bs; i++)
b[i] = new ArrayList<>();
for (int i = 0; i < a.length; i++) {
int idx = (a[i] - min) / SIZE;
b[idx].add(a[i]);
}
int idx = 0;
for (int i = 0; i < bs; i++) {
if (!b[i].isEmpty()) {
Collections.sort(b[i]); //这里也可以自己实现桶内排序
for (int x : b[i])
a[idx++] = x;
}
}
for (int i = 0; i < n; i++) {
System.out.print(a[i] + " ");
}
}
}