• 基数排序


    第一步

    以LSD为例,假设原来有一串数值如下所示:
    73, 22, 93, 43, 55, 14, 28, 65, 39, 81
    首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
    0
    1 81
    2 22
    3 73 93 43
    4 14
    5 55 65
    6
    7
    8 28
    9 39

    第二步

    接下来将这些桶子中的数值重新串接起来,成为以下的数列:
    81, 22, 73, 93, 43, 14, 55, 65, 28, 39
    接着再进行一次分配,这次是根据十位数来分配:
    0
    1 14
    2 22 28
    3 39
    4 43
    5 55
    6 65
    7 73
    8 81
    9 93

    第三步

    接下来将这些桶子中的数值重新串接起来,成为以下的数列:
    14, 22, 28, 39, 43, 55, 65, 73, 81, 93
    这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
    LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。

    实现方法

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

    实现原理

    基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
    基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
     1 #include<math.h>
     2 testBS()
     3 {
     4     inta[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
     5     int *a_p = a;
     6     //计算数组长度
     7     intsize = sizeof(a) / sizeof(int);
     8     //基数排序
     9     bucketSort3(a_p, size);
    10     //打印排序后结果
    11     inti;
    12     for(i = 0; i < size; i++)
    13     {
    14         printf("%d
    ", a[i]);
    15     }
    16     intt;
    17     scanf("%d", t);
    18 }
    19 //基数排序
    20 voidbucketSort3(int *p, intn)
    21 {
    22     //获取数组中的最大数
    23     intmaxNum = findMaxNum(p, n);
    24     //获取最大数的位数,次数也是再分配的次数。
    25     intloopTimes = getLoopTimes(maxNum);
    26     inti;
    27     //对每一位进行桶分配
    28     for(i = 1; i <= loopTimes; i++)
    29     {
    30         sort2(p, n, i);
    31     }
    32 }
    33 //获取数字的位数
    34 intgetLoopTimes(intnum)
    35 {
    36     intcount = 1;
    37     inttemp = num / 10;
    38     while(temp != 0)
    39     {
    40         count++;
    41         temp = temp / 10;
    42     }
    43     returncount;
    44 }
    45 //查询数组中的最大数
    46 intfindMaxNum(int *p, intn)
    47 {
    48     inti;
    49     intmax = 0;
    50     for(i = 0; i < n; i++)
    51     {
    52         if(*(p + i) > max)
    53         {
    54             max = *(p + i);
    55         }
    56     }
    57     returnmax;
    58 }
    59 //将数字分配到各自的桶中,然后按照桶的顺序输出排序结果
    60 voidsort2(int *p, intn, intloop)
    61 {
    62     //建立一组桶此处的20是预设的根据实际数情况修改
    63     intbuckets[10][20] = {};
    64     //求桶的index的除数
    65     //如798个位桶index=(798/1)%10=8
    66     //十位桶index=(798/10)%10=9
    67     //百位桶index=(798/100)%10=7
    68     //tempNum为上式中的1、10、100
    69     inttempNum = (int)pow(10, loop - 1);
    70     inti, j;
    71     for(i = 0; i < n; i++)
    72     {
    73         introw_index = (*(p + i) / tempNum) % 10;
    74         for(j = 0; j < 20; j++)
    75         {
    76             if(buckets[row_index][j] == NULL)
    77             {
    78                 buckets[row_index][j] = *(p + i);
    79                 break;
    80             }
    81         }
    82     }
    83     //将桶中的数,倒回到原有数组中
    84     intk = 0;
    85     for(i = 0; i < 10; i++)
    86     {
    87         for(j = 0; j < 20; j++)
    88         {
    89             if(buckets[i][j] != NULL)
    90             {
    91                 *(p + k) = buckets[i][j];
    92                 buckets[i][j] = NULL;
    93                 k++;
    94             }
    95         }
    96     }
    97 }
    View Code
  • 相关阅读:
    python网络编程 — HTTP客户端
    实验吧Web-天网管理系统
    实验吧Web-FALSE
    实验吧Web-Forms
    离散数学-集合运算基本法则
    sublime text3编译运行C,Java程序的一些配置
    kali Rolling 安装QQ和虚拟机
    python并行任务之生产消费模式
    Linux磁盘管理
    python网络编程之网络主机信息
  • 原文地址:https://www.cnblogs.com/wangmengmeng/p/4781683.html
Copyright © 2020-2023  润新知