高级排序之基数排序

1.什么是基数排序

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,借以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

2.基数排序图解

3.基数排序代码实现

     public static void radixSort(int[] nums) {
        int len = nums.length;
        int die = 10;
        int dividend = 1;
        Map<Integer, List<Integer>> map = new HashMap<>();
        int max = 0;
        do {//循环比较位数 个十百千万。。。
            for (int i = 0; i < len; i++) {
                if (nums[i] > max) {
                    max = nums[i];
                }
                int positionNum = nums[i] % die / dividend;
                List<Integer> list = map.getOrDefault(positionNum, new ArrayList<>());
                list.add(nums[i]);
                map.put(positionNum, list);
            }
            //比较位数后 除数 跟模均乘10
            die *= 10;
            dividend *= 10;

            //将排序的字段赋值回数组
            int index = 0;
            int nums_Index = 0;
            while (index < 10) {
                List<Integer> list = map.getOrDefault(index, new ArrayList<>());
                for (Integer integer : list) {
                    nums[nums_Index++] = integer;
                }
                map.remove(index);
                index++;
            }
        } while (dividend <= max);//当除数大于最大值后 不在继续
    }

4.基数排序的效率

初看起来 ,基数排序的执行效率似乎好得让人无法相信 。所有要做的只是把原始的数据项从数 组复制到链表 ,然后再复制回去 。如果有 IO 个数据项 ,则有 20 次复制。对每一位重复这个过程 。假设对 5 位的数字排序 ,就需要 20*5,等于100 次复制。如果有100 个数据项 ,那么就有 200*5 等于 1000 次复制 。复制的次数和数据项的个数成正比 ,即 O(N) ,这是我们看到的效率最高的排序 算法 。

不幸的是 ,一般是这样 :只要数据项越多 ,就需要越长的关键字 。如果数据项增加 10  倍 ,那 么关键字就需要再增加另一位 。复制的次数是和数据项的个数与关键字的位数的乘积成正比 。位数 是关键字值的对数 ,因此在绝大多数的情况下 ,算法的执行效率倒退为 O(N*logN),和快速排序算 法相同 。

尽管从数字中提取出每一位需要花费时间 ,但是没有比较。每两次复制需要一次位提取。然而, 一台给定的计算机在二进制中的位提取操作快于比较操作 。当然,与归并排序类似 ,基数排序所需 要的存储空间是快速排序的二倍 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章