十大排序之桶排序

public class RadixSort {
    public static void main(String[] args) {
//        int[] arr = {542,53,3,14,214,748};
//        时间复杂度 O(n+k) 稳定性好的 一种排序算法
        int [] arr = new int[80000];
        int[] temp = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            // 生成 [0,8000000)的随机数
            arr[i] = (int) (Math.random()*8000000);
        }
        long start_Time = System.currentTimeMillis();
        radixSort(arr);
        long stop_Time = System.currentTimeMillis();
        System.out.printf("耗费 %d ms",stop_Time - start_Time);

    }

    // 基数排序推导过程版
    public static void radix(int[] arr){
        //排序几轮是根据数组中的最大值的位数来决定的 例如 最大值是三位数的排序只用排三轮就能排序完成
        // 第一轮(针对每个元素的个位进行排序处理)
        /**
         * 定义一个二维数组,表示10个桶,每一个桶就是一个一维数组
         * 二维数组包含10个一维数组
         * 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
         * 基数排序使用空间换时间的算法
         */
        int[][] bucket = new int[10][arr.length];

        /**
         * 创建一个一维数组 记录每个桶中实际存放了多少个数据,
         * bucketElementCounts [0] 记录的就是bucket[0]桶中的放入数据的个数
         */
        int[] bucketElementCounts = new int[10];

        for (int i = 0; i <arr.length ; i++) {
             // 取出每个元素的个位数来决定存放到那个桶中
            int num =arr[i] % 10 ;
            //bucketElementCounts[num]++   第num 桶中有了多少个数据
            bucket[num][bucketElementCounts[num]++] = arr[i] ;

        }
        //按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
        int intdex = 0;
        //遍历每一个桶。并将桶中有数据的值,放入到原数组中
        for (int i = 0; i < bucketElementCounts.length; i++) {
            // 判断是否有是数据的桶才进入取出数据 减少循环次数
            if(bucketElementCounts[i] !=0){
                for (int j = 0; j < bucketElementCounts[i]; j++) {
                    arr [intdex++] = bucket[i][j];
                }
            }
        }
        intdex =0;
        System.out.println("========第一轮=========");

        System.out.println(Arrays.toString(arr));

        System.out.println("========第二轮=========");

        bucketElementCounts = new int[10];

        for (int i = 0; i <arr.length ; i++) {
            // 取出每个元素的十位数来决定存放到那个桶中
            int num =arr[i]  /10% 10 ;
            //bucketElementCounts[num]++   第num 桶中有了多少个数据
            bucket[num][bucketElementCounts[num]++] = arr[i] ;

        }

        //遍历每一个桶。并将桶中有数据的值,放入到原数组中
        for (int i = 0; i < bucketElementCounts.length; i++) {
            // 判断是否有是数据的桶才进入取出数据 减少循环次数
            if(bucketElementCounts[i] !=0){
                for (int j = 0; j < bucketElementCounts[i]; j++) {
                    arr [intdex++] = bucket[i][j];
                }
            }
        }
        intdex =0;
        System.out.println(Arrays.toString(arr));

        System.out.println("========第三轮=========");

        bucketElementCounts = new int[10];

        for (int i = 0; i <arr.length ; i++) {
            // 取出每个元素的百位数来决定存放到那个桶中
            int num =arr[i]  /100 ;
            //bucketElementCounts[num]++   第num 桶中有了多少个数据
            bucket[num][bucketElementCounts[num]++] = arr[i] ;

        }

        //遍历每一个桶。并将桶中有数据的值,放入到原数组中
        for (int i = 0; i < bucketElementCounts.length; i++) {
            // 判断是否有是数据的桶才进入取出数据 减少循环次数
            if(bucketElementCounts[i] !=0){
                for (int j = 0; j < bucketElementCounts[i]; j++) {
                    arr [intdex++] = bucket[i][j];
                }
            }
        }

        System.out.println(Arrays.toString(arr));


    }

    // 最终版
    public  static  void radixSort(int[] arr){
        int[][] bucket = new int[10][arr.length];
        int[] bucketElementCounts = new int[10];
        int intdex = 0;
        // 找出最大值 决定了排序的轮数
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(max < arr[i]){
                max = arr[i];
            }
        }
        // 获取排序的轮数
        int maxLength = (max +"").length();

        for (int j = 0, n =1 ; j <maxLength ; j++ , n *= 10) {
            for (int i = 0; i <arr.length ; i++) {
                // 取出每个元素的位数来决定存放到那个桶中
                int num =arr[i] /n % 10 ;
                //bucketElementCounts[num]++   第num 桶中有了多少个数据
                bucket[num][bucketElementCounts[num]++] = arr[i] ;

            }
             intdex =0;
            //遍历每一个桶。并将桶中有数据的值,放入到原数组中
            for (int i = 0; i < bucketElementCounts.length; i++) {
                // 判断是否有是数据的桶才进入取出数据 减少循环次数
                if(bucketElementCounts[i] !=0){
                    for (int k = 0; k < bucketElementCounts[i]; k++) {
                        arr [intdex++] = bucket[i][k];
                    }
                }
                // 获取了数据之后重新把每一个元素置为零
                bucketElementCounts[i] =0;
            }
//            System.out.printf("第%d轮排序:%s\n",j+1,Arrays.toString(arr));
        }

    }
}
发布了39 篇原创文章 · 获赞 13 · 访问量 2292

猜你喜欢

转载自blog.csdn.net/qq_43205282/article/details/105399465