桶排序(Bucket sort)
桶排序
桶排序(Bucket sort) 是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。
算法描述
- 设置一个定量的数组当作空桶;
- 遍历输入数据,并且把数据一个一个放到对应的桶里去;
- 对每个不是空的桶进行排序;
- 从不是空的桶里把排好序的数据拼接起来。
算法分析
时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|
\(O(n+k)\) | \(O(n^2)\) | \(O(n)\) | \(O(n+k)\) | 稳定 |
例子
![](https://images.cnblogs.com/cnblogs_com/blogs/734424/galleries/2112342/o_220221110926_%E6%A1%B6%E6%8E%92%E5%BA%8F.gif)
代码
Java
public static double[] bucketSort(double[] array){
//1.得到数列的最大值和最小值,并算出差值d
double max = array[0];
double min = array[0];
for(int i=1; i<array.length; i++) {
if(array[i] > max) {
max = array[i];
}
if(array[i] < min) {
min = array[i];
}
}
double d = max - min;
//2.初始化桶
int bucketNum = array.length;
ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);
for(int i = 0; i < bucketNum; i++){
bucketList.add(new LinkedList<Double>());
}
//3.遍历原始数组,将每个元素放入桶中
for(int i = 0; i < array.length; i++){
int num = (int)((array[i] - min) * (bucketNum-1) / d);
bucketList.get(num).add(array[i]);
}
//4.对每个桶内部进行排序
for(int i = 0; i < bucketList.size(); i++){
//JDK底层采用了归并排序或归并的优化版本
Collections.sort(bucketList.get(i));
}
//5.输出全部元素
double[] sortedArray = new double[array.length];
int index = 0;
for(LinkedList<Double> list : bucketList){
for(double element : list){
sortedArray[index] = element;
index++;
}
}
return sortedArray;
}
python
def bucktetSort(numList,bucketNum):
if len(numList) == 0 or len(numList) == 1:
return numList
maxNum = numList[0]
minNum = numList[0]
for i in range(1,len(numList)): # 找到最大最小值
if numList[i] < minNum:
minNum = numList[i]
elif numList[i] > maxNum:
maxNum = numList[i]
else:
continue
bucketSize = (maxNum - minNum + 1) // bucketNum # 根据桶的数量找到每个桶的范围
buckets = [[] for i in range(bucketNum)]
for i in range(len(numList)): # 将各个数分配到各个桶
buckets[(numList[i] - minNum) // bucketSize].append(numList[i])
for i in range(bucketNum): # 桶内排序,可以使用各种排序方法
buckets[i].sort()
res = []
for i in range(len(buckets)): # 分别将各个桶内的数提出来,压入结果
for j in range(len(buckets[i])):
res.append(buckets[i][j])
return res