桶排序(Bucket sort)

桶排序

桶排序(Bucket sort) 是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

算法描述

  1. 设置一个定量的数组当作空桶;
  2. 遍历输入数据,并且把数据一个一个放到对应的桶里去;
  3. 对每个不是空的桶进行排序;
  4. 从不是空的桶里把排好序的数据拼接起来。

算法分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
\(O(n+k)\) \(O(n^2)\) \(O(n)\) \(O(n+k)\) 稳定

例子

代码

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
posted @ 2022-02-24 09:03  morning-start  阅读(35)  评论(0编辑  收藏  举报