定义
桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。
思路
将要排序的数据分到几个有序的桶中,每个桶里的数据在单独进行排序。桶内排完序之后,再把每个桶里的数据按照顺序依次取出来,组成的序列就是有序的了。
对数组[5, 25, 34, 12, 4, 9, 18, 26, 22, 24, 36, 48, 0, 46, 50]进行桶排序:
代码实现
// 桶排序
public class BucketSort {
public static void bucketSort(int[] arr) {
if (arr == null || arr.length < 2) return;
// 找到最大最小值
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) max = arr[i];
if (arr[i] < min) min = arr[i];
}
int d = max - min;
// 桶的数量,每个桶的范围是5(根据数组大小选取),最后一个桶只存放最大数
int bucketNum = d / 5 + 1;
List<LinkedList<Integer>> bucketList = new ArrayList<>();
// 初始化桶
for (int i = 0; i < bucketNum; i++) {
bucketList.add(new LinkedList<>());
}
// 将每个数放到对应的桶中
for (int i = 0; i < arr.length; i++) {
// d/(bucketNum - 1)表示每个桶的范围 num为a[i]应该放入的桶
int num = (arr[i] - min) * (bucketNum - 1) / d;
bucketList.get(num).add(arr[i]);
}
// 对每个桶中的数进行排序
for (LinkedList<Integer> integers : bucketList) {
// JDK底层采用了归并排序或归并的优化版本
Collections.sort(integers);
}
// 将桶中的数放回数组
int k = 0;
for (LinkedList<Integer> integers : bucketList) {
for (Integer integer : integers) {
arr[k++] = integer;
}
}
}
}
性质
1.时间复杂度:O(n+k)
2.空间复杂度:O(n+k)
3.稳定排序
4.非原地排序