写点什么

十大排序算法 -- 桶排序

用户头像
阿粤Ayue
关注
发布于: 2 小时前
十大排序算法--桶排序

桶排序

桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序),最后将非空桶中的元素逐个放入原序列中。


桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。


代码实现

  1. 找出数组中的最大值 max 和最小值 min,可以确定出数组所在范围 min~max

  2. 根据数据范围确定桶的数量

  3. 若桶的数量太少,则桶排序失效

  4. 若桶的数量太多,则有的桶可能,没有数据造成空间浪费

  5. 所以桶的数量由我们自己来确定,但尽量让元素平均分布到每一个桶里,这里提供一个方式

  6. (最大值 - 最小值)/每个桶所能放置多少个不同数值+1

  7. 确定桶的区间,一般是按照(最大值 - 最小值)/桶的数量来划分的,且左闭右开


public class BucketSort {    public static final int[] ARRAY = {35, 23, 48, 9, 16, 24, 5, 11, 32, 17};    /**     * @param bucketSize 作为每个桶所能放置多少个不同数值,即数值的类型     *                   例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,     *                   但是容量不限,即可以存放100个3     */    public static List<Integer> sort(List<Integer> array, int bucketSize) {        if (array == null || array.size() < 2)            return array;        int max = array.get(0), min = array.get(0);        // 找到最大值最小值        for (int i = 0; i < array.size(); i++) {            if (array.get(i) > max)                max = array.get(i);            if (array.get(i) < min)                min = array.get(i);        }        //获取桶的数量        int bucketCount = (max - min) / bucketSize + 1;        //构建桶,初始化        List<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);        List<Integer> resultArr = new ArrayList<>();        for (int i = 0; i < bucketCount; i++) {            bucketArr.add(new ArrayList<>());        }        //将原数组的数据分配到桶中        for (int i = 0; i < array.size(); i++) {            //区间范围            bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));        }        for (int i = 0; i < bucketCount; i++) {            if (bucketSize == 1) {                for (int j = 0; j < bucketArr.get(i).size(); j++)                    resultArr.add(bucketArr.get(i).get(j));            } else {                if (bucketCount == 1)                    bucketSize--;                //对桶中的数据再次用桶进行排序                List<Integer> temp = sort(bucketArr.get(i), bucketSize);                for (int j = 0; j < temp.size(); j++)                    resultArr.add(temp.get(j));            }        }        return resultArr;    }    public static void print(List<Integer> array) {        for (int i : array) {            System.out.print(i + "  ");        }        System.out.println("");    }    public static void main(String[] args) {        print(Arrays.stream(ARRAY).boxed().collect(Collectors.toList()));        System.out.println("============================================");        print(sort(Arrays.stream(ARRAY).boxed().collect(Collectors.toList()), 2));    }}
复制代码

时间复杂度

桶排序算法遍历了 2 次原始数组,运算量为 2N,最后,遍历桶输出排序结果的运算量为 N,初始化桶的运算量为 M。


对桶进行排序,不同的排序算法算法复杂度不同,冒泡排序算法复杂度为 O(N^2),堆排序、归并排序算法复杂度为 O(NlogN),我们以排序算法复杂度为 O(NlogN)进行计算,运算量为 N/M * log(N/M) * M


最终的运算量为 3N+M+N/M * log(N/M) * M,即 3N+M+N(logN-logM),去掉系数,时间复杂度为 O(N+M+N(logN-logM))


参考:桶排序算法详解

算法稳定性

桶排序算法在对每个桶进行排序时,若选择稳定的排序算法,则排序后,相同元素的位置不会发生改变,所以桶排序算法是一种稳定的排序算法。

发布于: 2 小时前阅读数: 2
用户头像

阿粤Ayue

关注

微信搜:Javatv 2019.10.16 加入

学习知识,目光坚毅

评论

发布
暂无评论
十大排序算法--桶排序