一、桶排序适用数据范围
桶排序可用于最大最小值相差较大的数据情况,比如[9012,19702,39867,68957,83556,102456]。但桶排序要求数据的分布必须均匀,否则可能导致数据都集中到一个桶中。比如[104,150,123,132,20000], 这种数据会导致前4个数都集中到同一个桶中。导致桶排序失效。
二、桶排序过程分析
桶排序的基本思想是:将一个数据表分割成许多个bucket(桶),然后每个bucket可以各自排序(可以采用不同的排序算法)。它是典型的分而治之的策略。
具体的算法思想:
假设有一组长度为n的待排关键字序列K[1….n]。首先将这个序列划分成M个的子区间(桶) 。然后基于某种映射函数 ,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为n/M的序列)。接着对每个桶B[i]中的所有元素进行比较排序(可以使用快排)。然后依次枚举输出B[0]….B[M]中的全部内容即是一个有序序列。
【桶排序关键】映射函数
index=f(key), 其中index为桶数组B的下标(即第index个桶), key为待排序列的关键字。桶排序之所以能够高效,其关键在于这个映射函数,它必须做到:如果关键字key1<key2,那么f(key1)<=f(key2)。也就是说B(i)中的最小数据都要大于B(i-1)中最大数据。很显然,映射函数的确定与数据本身的特点有很大的关系。
桶排序的动态演示:
地址:https://www.cs.usfca.edu/~galles/visualization/BucketSort.html
注意:计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
桶排序算法步骤:
1.找出待排序数组中的最大值max、最小值min
2.我们使用动态数组ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(max-min)/arr.length+1
3.遍历数组 arr,计算每个元素 arr[i] 放的桶
4.每个桶各自排序
5.遍历桶数组,把排序好的元素放进输出数组
三、桶排序实例
比如有数据{32, 43, 1, 65, 43, 57, 83, 93, 73, 22, 28, 53},这些数据在区间[0, 100)中,将这些数据分进十个桶中(注意:这里桶的数量是自己定义的),然后在这些桶中对其中的数据进行排序。如下图所示:
四、桶排序代码实现
import java.util.ArrayList;
import java.util.Collections;
public class bucketSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {32, 43, 1, 65, 43, 57, 83, 93, 73, 22, 28, 53};
ArrayList result = BucketSort(array);
System.out.println(result.toString());
}
public static ArrayList BucketSort(int[] arr) {
int min = arr[0];
int max = arr[0];
for(int i=0; i<arr.length; i++) {
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
//桶个数
int bucketNum = (max -min) / arr.length +1;
//构造桶
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for(int i=0; i<bucketNum; i++) {
bucketArr.add(new ArrayList<Integer>());
}
// 将每个元素放入桶中
for(int i=0; i<arr.length; i++) {
int num = (arr[i] - min) / (arr.length);
bucketArr.get(num).add(arr[i]);
}
//对每个桶进行排序
for(int i=0; i<bucketArr.size(); i++) {
Collections.sort(bucketArr.get(i));
}
return bucketArr;
}
}
五、时间复杂度和空间复杂度分析
1. 桶排序的平均时间复杂度是线性的,即O(n)。
2. 桶排序中,需要创建M个桶的额外空间,以及N个元素的额外空间。
3. 桶排序算法是稳定算法。
六、Reference
【1】https://www.cnblogs.com/zer0Black/p/6169858.html
【2】https://www.cs.usfca.edu/~galles/visualization/BucketSort.html
【3】https://blog.csdn.net/wodedipang_/article/details/63268624
【4】https://juejin.im/post/5b4f55676fb9a04fb745d0df
【5】https://blog.csdn.net/u010647471/article/details/49522603