zoukankan      html  css  js  c++  java
  • 排序算法(10)--Distribution Sorting--分布排序[2]--Radix Sort--基数排序

    1.基本思想

      基数排序是通过“分配”和“收集”过程来实现排序

    2.实现原理

      基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:

        (1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)

        (2)收集,再将放置在0~9号桶中的数据按顺序放到数组中

      重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)

    3.代码实例

    (1)代码:

         

     //pos=1表示个位,pos=2表示十位
    public static int getNumInPos(int num, int pos) {
        int tmp = 1;
        for (int i = 0; i < pos - 1; i++) {
            tmp *= 10;
        }
        return (num / tmp) % 10;
    }
    
    //求得最大位数d
    public static int getMaxWeishu(int[] a) {
        int max = a[0];
        for (int i = 0; i < a.length; i++) {
            if (a[i] > max)
                max = a[i];
        }
        int tmp = 1, d = 1;
        while (true) {
            tmp *= 10;
            if (max / tmp != 0) {
                d++;
            } else
                break;
        }
        return d;
    }
    
    public static void radixSort(int[] a, int d) {
        int[][] array = new int[10][a.length + 1];
        for (int i = 0; i < 10; i++) {
            array[i][0] = 0;// array[i][0]记录第i行数据的个数
        }
        for (int pos = 1; pos <= d; pos++) {
            for (int i = 0; i < a.length; i++) {// 分配过程
                int row = getNumInPos(a[i], pos);
                int col = ++array[row][0];
                array[row][col] = a[i];
            }
            for (int row = 0, i = 0; row < 10; row++) {// 收集过程
                for (int col = 1; col <= array[row][0]; col++) {
                    a[i++] = array[row][col];
                }
                array[row][0] = 0;// 复位,下一个pos时还需使用
            }
        }
    }
    
    public static void main(String[] args) {
        int[] a = { 49, 38, 65, 197, 76, 213, 27, 50 };
        radixSort(a, getMaxWeishu(a));
        for (int i : a)
            System.out.print(i + " ");
    }

    (2)结果:

     27 38 49 50 65 76 197 213

    4.算法分析

            该算法所花的时间基本是在把元素分配到桶里和把元素从桶里串起来;把元素分配到桶里:循环 length 次;

           把元素从桶里串起来:这个计算有点麻烦,看似两个循环,其实第二循环是根据桶里面的元素而定的,可以表示为:k×buckerCount;其中 k 表示某个桶中的元素个数,buckerCount  则表示存放元素的桶个数;

           有几种特殊情况:

           第一、所有的元素都存放在一个桶内:k = length,buckerCount = 1;

           第二、所有的元素平均分配到每个桶中:k = length/ bukerCount,buckerCount = 10;(这里已经固定了10个桶)

           所以平均情况下收集部分所花的时间为:length (也就是元素长度 n)

           综上所述:

           时间复杂度为:posCount * (length  + length) ;其中 posCount 为数组中最大元素的最高位数;简化下得:O( k*n ) ;其中k为常数,n为元素个数;

            该算法的空间复杂度就是在分配元素时,使用的桶空间;所以空间复杂度为:O(10 × length)= O(length)

  • 相关阅读:
    EF生成的SQL语句执行顺序问题。
    关于scope_identity()与 @@IDENTITY
    按条件设置gridcontrol 单元格属性
    DevExpress gridcontrol Master-Detail绑定到对象类型
    dev ChartControl 备忘
    gridcontrol 图片列异步加载
    关于EmitMapper,映射配置
    asp.net Hessian 服务的注册
    XtrasReport 标签打印
    Devexpress + wcf +ef 批量更新处理
  • 原文地址:https://www.cnblogs.com/yysbolg/p/8716436.html
Copyright © 2011-2022 走看看