• 数组排序-基数排序(Radix Sort)



    概念:

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


    实现方法:

        最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便起到一个有序序列。
        最低位优先(Least Significance Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。


    实现原理:

        基数排序的发明可以追溯导1887年,赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
        基数排序的方式可以采用LSD(Least significance digital)或MSD(Most significance digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。


    示例:

    package com.cnblogs.lxj.testarraysort;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @packageName: com.cnblogs.lxj.testarraysort
     * @className: RadixSort
     * @description: 测试基数排序
     * @author: liuxiaojiang
     * @date: 2021/1/8
     */
    public class RadixSort {
    
        public static void main(String[] args) {
            int[] a = new int[]{321,1,10,60,577,743,127};
            printArray(a);
            radixSortOne(a,10,3);
            printArray(a);
        }
    
        /**
         * @description: 基数排序方法(1)
         * @author: liuxiaojiang
         * @date: 2021/1/8
         * @param a: 代表数组
         * @param radix: 代表基数
         * @param d: 代表排序元素的位数
         * @return: void
         **/
        public static void radixSortOne(int[] a,int radix,int d){
            List<List<Integer>> ts = new ArrayList<List<Integer>>();
            int rate = 1;
            for(int i = 0;i < radix;i++){
                List<Integer> t = new ArrayList<Integer>();
                ts.add(t);
            }
            for(int i = 0;i < d;i++){
                for(int j = 0;j < radix;j++){
                    List<Integer> t = ts.get(j);
                    t.clear();
                }
                for(int j = 0;j < a.length;j++){
                    int subKey = (a[j]/rate) % radix;
                    List<Integer> t = ts.get(subKey);
                    t.add(a[j]);
                }
                int count = 0;
                for(int j = 0; j < radix;j++){
                    List<Integer> t = ts.get(j);
                    for(int k = 0;k < t.size();k++){
                        a[count++] = t.get(k);
                    }
                }
                rate *= radix;
                System.out.print("第"+(i+1)+"次:");
                printArray(a);
            }
        }
    
        /**
         * @description: 基数排序方法(2)
         * @author: liuxiaojiang
         * @date: 2021/1/8
         * @param array: 代表数组
         * @param radix: 代表基数
         * @param d: 代表排序元素的位数
         * @return: void
         **/
        public static void radixSortTwo(int[] array,int radix,int d){
            int[] tempArray = new int[array.length];
            int[] count = new int[radix];
            int rate = 1;
            for(int i = 0;i < d;i++){
                Arrays.fill(count,0);
                System.arraycopy(array,0,tempArray,0,array.length);
                for(int j = 0;j < array.length;j++){
                    int subKey = (tempArray[j] / rate) % radix;
                    count[subKey]++;
                }
                for(int j = 1;j < radix;j++){
                    count[j] = count[j] + count[j - 1];
                }
                for(int m = array.length - 1;m >= 0;m--){
                    int subKey = (tempArray[m] / rate) % radix;
                    array[--count[subKey]] = tempArray[m];
                }
                rate *= radix;
                System.out.print("第"+(i+1)+"次:");
                printArray(array);
            }
        }
    
        /**
         * @description: 输出方法
         * @author: liuxiaojiang
         * @date: 2021/1/8
         * @param array: 代表数组
         * @return: void
         **/
        public static void printArray(int[] array){
            for(int i : array){
                System.out.print(i+" ");
            }
            System.out.println();
        }
    
    }
    

    运行结果:

    321 1 10 60 577 743 127       //初始化
    第1次:10 60 321 1 743 577 127 
    第2次:1 10 321 127 743 60 577 
    第3次:1 10 60 127 321 577 743 
    1 10 60 127 321 577 743       //最终结果
    

    原理:


  • 相关阅读:
    cocos2d-x3.0 PageView
    mysql 安装配置及经常使用操作
    Android自己定义组件系列【6】——进阶实践(3)
    hdu 4300 Clairewd’s message(具体解释,扩展KMP)
    VS&quot;后生成事件&quot; 菜单的使用
    CUDA 实现JPEG图像解码为RGB数据
    Hibernate操作Blob数据
    android清除缓存为什么总是存在12k?
    JSP入门
    Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
  • 原文地址:https://www.cnblogs.com/joyfulcode/p/14153658.html
Copyright © 2020-2023  润新知