算法之桶排序

思想:正如网上大部分文章所说,桶排序就是把原始数组的数据防放入各个桶中。然后对桶再排序,然后把每个桶的数据依次输出到原始数组就可以了,我自己写了个简陋版本的,不求效率,只求简易实现。我自己写这个效率很低,有时间再改进吧。。

public class BucketSort {
    @Autowired
    private ShellSort shellSort;

    public static void main(String[] args) {
        int[] arr = new int[100];  //构建一个空的一维数组
        for (int i = 0; i < arr.length; i++) {
            int temp = (int) (Math.random() * 1000) + 1;//随机产生一个 1~10 的整数
            arr[i] = temp;//将产生的数添加到数组
        }
        long a = System.currentTimeMillis();
        int[] array = busketSort(arr,10);
        long b = System.currentTimeMillis();
        System.out.println(b - a + "毫秒");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(array[i]);
        }
    }

    // 数组  和桶的个数
    public static int[] busketSort(int[] array,int count) {
        // 初始化桶 利用二维数组 我这里每一个桶长度都等于原来数组长度,所以效率低,之所以是这样,是因为我还没找到一种
        // 如何得知每个桶数据的大小,所以都给他们设为最大值。
        int[][] bucketArray = new int[count][ array.length];
        for (int i = 0; i < array.length; i++) {
            // 得到数据在哪个桶
            int index = getIndex(array[i],count);
            // 把数据存进对应的桶
            bucketArray[index][i] = array[i];
        }
        // 对桶进行排序
        int[] ints = sort1(bucketArray, array);
        return ints;
    }

    public static int[] sort1(int[][] bucketArray, int[] array) {
        for (int i = 0; i < bucketArray.length; i++) {
            // 取对应的桶
            int[] ints = bucketArray[i];
            //调用希尔排序对每个桶排序  希尔排序可以参考我另一篇文章  这里不贴代码了
            ShellSort.sort(ints);
        }
        //组装数据
        int index = 0;
        // 一维数组  代表列
        for (int i = 0; i < bucketArray.length; i++) {
            // 二维数组 代表行
            for (int j = 0; j < bucketArray[i].length; j++) {
                // 若数组有值  则存进去  这里会有数据损失  0不会存进去  有待优化
                if (bucketArray[i][j] > 0) {
                    array[index] = bucketArray[i][j];
                    index++;
                }
            }
        }
        return array;
    }

    // 根据桶的容量和数组中最小值求得数据在哪个桶
    public static int getIndex(int a, int min, int capacity) {
        //
        return (a - min) / capacity;
    }

}

思考桶排序的关键点:
1.在于如何确定桶的个数以及每个桶所存储的数据量。每个桶的容量应该是相同的
公式如下:
桶的个数*桶的容量大于等于数组中的最大值-最小值 桶之间的间距和桶的容量相等。

    // 根据桶的容量和数组中最小值求得数据在哪个桶
    public static int getIndex(int a, int min, int capacity) {
        //
        return (a - min) / capacity;
    }

    // 根据桶的容量求得桶的数量
    public static int getBucketCount(int[] array, int capacity, int max, int min) {

        // 桶的个数*桶的容量大于等于数组中的最大值-最小值  桶之间的间距和桶的容量相等。
        int count = 0;

        return count = (max - min) / capacity + 1;
    }

    // 根据桶的数量求得桶的容量
    public static int getBucketLength(int[] array, int count, int max, int min) {

        // 桶的个数*桶的容量大于等于数组中的最大值-最小值  桶之间的间距和桶的容量相等。
        int capacity = 0;

        return capacity = (max - min) / count + 1;
    }

维基百科桶排序:
利用ArrayList来对数据排序,

    public static void main(String[] args) {
        int[] arr = new int[10];  //构建一个空的一维数组
        for (int i = 0; i < arr.length; i++) {
            int temp = (int) (Math.random() * 100) + 1;//随机产生一个 1~10 的整数
            arr[i] = temp;//将产生的数添加到数组
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("----------------------------------");
        long a = System.currentTimeMillis();
        int[] array = busketSort(arr, 10);
        long b = System.currentTimeMillis();
        System.out.println(b - a + "毫秒");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(array[i]);
        }
    }


    // 数组  和桶的个数
    public static int[] busketSort(int[] array, int count) {

        int max = array[0], min = array[0];
        for (int i = 0; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
            if (array[i] < min) {
                min = array[i];
            }
        }
        // 初始化创建桶
        List bucketList = new ArrayList<List<Integer>>();
        for (int i = 0; i < count; i++) {
            //根据count 创建桶的个数
            bucketList.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < array.length; i++) {
            // 得到数据应该在哪个桶
            int index = getIndex(array[i], min, count);
            // 把数据存进对应的桶
            ((ArrayList<Integer>) bucketList.get(index)).add(array[i]);

        }
        ArrayList<Integer> bucket = null;
        int index = 0;
        for (int i = 0; i < count; i++) {
            bucket = (ArrayList<Integer>) bucketList.get(i);
            insertSort(bucket);
            for (int k : bucket) {
                array[index++] = k;
            }
        }
        return array;
    }

    // 把桶內元素插入排序
    private static void insertSort(List<Integer> bucket) {
        for (int i = 1; i < bucket.size(); i++) {
            int temp = bucket.get(i);
            int j = i - 1;
            for (; j >= 0 && bucket.get(j) > temp; j--) {
                bucket.set(j + 1, bucket.get(j));
            }
            bucket.set(j + 1, temp);
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值