桶排序

前言

最近在学数据结构与算法,在此做一下记录,方便时不时复习一下。如果有什么做得不对的地方,恳请指出,万分感谢。

简述

桶排序的工作原理:假设输入数据服从均匀分布,利用某种函数的映射关系将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或者是以递归方式继续使用桶排序)。桶排序利用函数的映射关系,减少了几乎所有的比较关系。实际上,桶排序的f(k)值的计算,其作用就相当于快排中的划分,已经把大量数据分割成了基本有序的数据块(桶),然后只需要对桶中的少量数据做排序即可。

步骤

1.判断数组是否为空或数组大小是否小于2,满足则return;

2.定义最大值max,最小值min,用于获得桶的数量以及分配数据;

3.计算桶的数量bucketCount;

4.构建桶bucketArr及存放最终数据的集合resultArr;

5.将原数组中的数据分配到桶中;

6.遍历所有的桶,根据每个桶中允许存放不同的值bucketSize的大小做出判断;

7.bucketSize为1时,将桶bucketArr中所有的值都取出放到集合resultArr中;

8.bucketSize不为1时,先判断bucketCoun是否为1,为1时,bucketSize--,不为1时什么都不用做。然后定义一个集合temp,递归调用第一步,最后对集合temp进行遍历,将数据放到集合resultArr中。

图示

代码

public class BucketSort {

    public final static int[] DATA = {34,22,47,8,15,23,4,10,33,17};

    public static void main(String[] args) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < DATA.length; i++) {
            arrayList.add(DATA[i]);
        }
        printObject(arrayList);
        System.out.println("==================================");
        ArrayList<Integer> dest = sort(arrayList,2);
        printObject(dest);

    }

    /**
     * 桶排序算法
     * @param array
     * @param bucketSize 作为每个桶所能放多少个不同的数值标识
     *                   (比如当bucketSize==4时,这个桶里面可以放4种不同的数字,
     *                   但是容量不限,可以放无数个一样的数字(可以存放100个2))
     * @return
     */
    public static ArrayList<Integer> sort(ArrayList<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;
        System.out.println("桶的个数为:" + bucketCount + "个");
        //构建桶
        ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
        ArrayList<Integer> resultArr = new ArrayList<>();
        for (int i = 0; i < bucketCount; i++) {
            bucketArr.add(new ArrayList<Integer>());
        }
        //将原数组中的数据分配到桶中
        for (int i = 0; i < array.size(); i++) {
            bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
        }
        //查看一下桶的分布情况
        for (int i = 0; i < bucketArr.size(); i++) {
            System.out.print("第"+i+"个桶中的数据为:");
            printObject(bucketArr.get(i));
        }
        //遍历所有的桶,根据桶中个数做出判断
        System.out.println("bucketSize为:" + bucketSize);
        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--;

                //对桶中的数据再用次用桶进行排序
                ArrayList<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 printObject(ArrayList<Integer> array) {
        for (int i : array) {
            System.out.print(i+" ");
        }
        System.out.println("");
    }

}

结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值