基本思想
原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值均匀分配的时候,桶排序使用线性时间O(n)。但桶排序并不是比较排序,他不受到O(nlogn)下限的影响。
算法描述
- 设置一个定量的数组当作空桶
- 遍历输入数据,并且把数据一个一个放到对应的桶里去
- 对每个不是空的桶进行排序
- 从不是空的桶里把排好序的数据拼接起来
演示
代码实现
public static void sort(int[] array) {
// 最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
// 最大位数
int maxLen = Integer.toString(max).length();
// 十个桶,每个桶最多能放排序数组
int[][] s = new int[10][array.length];
// 记录每个桶放了多少数据
int[] k = new int[10];
for (int m = 0; m < maxLen; m++) {
for (int i = 0; i < array.length; i++) {
int mod = array[i] / (int) (Math.pow(10D, Double.valueOf(m + ""))) % 10;// 获取个位数
s[mod][k[mod]] = array[i];
k[mod] = k[mod] + 1;
}
int index = 0;
for (int i = 0; i < 10; i++) {
if (k[i] > 0) {
for (int j = 0; j < k[i]; j++) {
array[index++] = s[i][j];
}
}
}
k = new int[10];
}
}
时间复杂度
N个数据平均的分配到M个桶中,这样每个桶就有[N/M]个数据量
桶排序平均时间复杂度为:O(N)+O(M*(N/M)log(N/M))=O(N+N(logN-logM))=O(N+NlogN-NlogM)
当N=M时,即极限情况下每个桶只有一个数据时。桶排序的最好效率能够达到O(N)。
最佳情况:O(N)
最佳情况:O(n^2)
平均情况:O(N+C),其中C=N(logN-logM)*
空间复杂度
O(m) m在这里表示最大值
优点与缺点
- 优点:实现简单,排序速度快于任何比较排序
- 缺点:不稳定,只适用于小整数的排序
测试记录
待补充
源码
暂时未发现在开源框架或jdk中用到插入排序
基数排序,计数排序和桶排序
- 都是非比较的排序算法
- 基数排序和计数排序都可以看作是桶排序。计数排序本质上是一种特殊的桶排序,当桶的个数取最大的时候,就变成了计数排序。
- 基数排序也是一种桶排序。桶排序是按值区间划分桶,基数排序是按位数划分;基数排序可以看作是多轮桶排序,每个数位上都进行一轮桶排序。
- 当用最大值作为基数时,基数排序就退化成了计数排序。