当前位置:首页 > 百科

基数排序

基数排序(radi来自x sort)属于"分配式排序"(distribution sort),又称"桶子法"(buck告钢候et sort)冲夜量值议井尽火征或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些"桶"中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数360百科,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

  • 中文名 基数排序
  • 外文名 Radix sort
  • 类别 分配式排序
  • 别称 “桶子法”
  • 方法 最高位优先法和最低位优先

基本解法

第一步

  以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 8来自1

  9 93

第三步

  接下沙前子讨刑每来将这些桶子中的数值重新串接起来,成为以下的数列:

  14, 22, 28, 39, 43, 55, 65, 73, 81, 9360百科3

  这时候整个数列已经排序花方石完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。

  LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行太鲜除细限和念叫场名福分配,但在分配之列商持怕验课坐后并不马上合并回一个数组中,而是在每个"桶子"中建最理还志脸令当日刻立"子桶",将每个桶子中的数值按照下一数位的值分配到"子桶"中。在进行完最低位数的分配后再合并回单一的数组中。

效率分析

 伟放有设草频婷即松 时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为功蛋易沙施集radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和养先出掉收集。 空间效率:需要2*radix个指向队列的辅助顶回神阻等陈半资老角胞空间,以及用于静态链表的n个指针。

实现方法

  最高来自位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组360百科连接起来,便得到一个有序序列。

  最低位优先(Least Significant Dig难德it first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到爱机保著被愿及宽困对k1排序后便得到一个有序序列。

实现原理

  基数排序的发明蛋器玉卷采余重毛台半岩可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面员视守本石为严承补零。然后,从最低位开始,依次进行一次排序末务岩十围轮几盾修船青。这样从最低位排序条书感燃病河育封场一直到最高位排序完成以后, 数列就变成一个有序序列。

  基数排序的方式可以采用LSD(Least signific营血卷题茶主之ant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

AAuto

第一步

  io.open(钢块亚同气诉尔起困溶);//打开控制台

 田友试将 /*

  *-------------------------------------------------------

  * 基数排序

  **----------------------------------------尼煤--------------

  */

  /*

第二步

  基数排序从低位到高位进行,使得最后一次计数排序完成后,数组有序。

  其原理在于对于待排序的数据,整体权重未知的情况下,

  先按权重小的因子排序,然后按权重大的因子排序。

  例如比较让今守啊散赵时站顾来等时间,先按日排序,再按月排序,最后按年排验至普字钱约制地支穿序,仅需排序三次。

  但是如果先排序高位就没这么简单了

  基数排序源于老式穿孔机,排序器每次只能看到一个列,

  很多教科书上的基数排序都是对数值排序,数值的大小是已知的,与老式穿孔机不同。

  将数值按位拆分再排序,是无聊并自找麻烦的事。

  算法的目的是找到最佳解决问题的方案,而不是把简单的事搞的更复杂。

  基数排序更适合用于对时间、字符串等这些整体权值未知的数据进行排序。

  这时候基数排雷些表序的思想才能体现出来,例如字符串,如果从高位(第一位)往后排就很麻烦。

  而反过来,先对影响力较小,排序排重因子较小的低位(最后一位)进行排序就非常简单了。

  这时候基数排序的思想就能体现出来。

  又或者所有的数值都是以字符串形式存储,就象穿孔机一样,及继品训探刻祖学每次只能对一列进行排序。

  这时候基数排序也适用,例如:对{"193";"229";"233";"215"}进行排序

  下面我们使用基数排慢曾热宗批序对字符串进行排序。

  对每个位循环调用计数排序。

  */

第三步

  //计数排序算法

  radix_sort = function( array ,maxlen){

  //AAuto在字符串索引越界时,会返回0,这使基数排序的实现更加简单。

  //我们首先找出最大的排序长度,然后对于不足此长度的字符串,尾部都假定以0补齐。

  //对于超出此长度的位在比较时忽略

  if(!maxlen){

  maxlen =0;

  for(i=1;#array;1){

  maxlen = math.max(maxlen,#array[i] )

  }

  }

  //else{

  //最大排序长度也可以从参数中传棉诉艺掌威极娘终富厂过来,这样就不用遍历所有字符串了

  //}

第四步

  //从字符串的最后一位开始,到第一位

  for(pos=maxlen;1;-1){

  //按当前位的字节码计数排序

  var array_sorted ={};

  var count = {};

  for(i=0;256 ){

  count[i] = 0;

  }

  var bytecode;

  for(i=1;#array;1){

  //如果pos大于字符串长度,AAuto会返回0,这使基数排序的实现更容易

  bytecode = array[i][pos] ;

  count[ bytecode ] ++; //count[n] 包含等于n的个数

  }

第五步

  //统计位置

  for(i=1;256;1){

  count[i] += count[i-1]; //count[i] 包含小于等于i的个数

  }

  var n;

  for(i=#array;1;-1){

  n = array[i][pos]

  array_sorted[ count[n] ] = array[i];

  count[n]--;//防止相同的元素n再次出现,将计数减一

  }

  array = array_sorted;

  }

  return array

  }

  io.print("----------------")

  io.print("基数排序( 线性时间排序 )")

  io.print("----------------")

  array ={"AAuto is quicker and better,just try it!";"AAuto Quicker";"193";"229";"233";"215";"Hello Word";"abc";"abcd";"xd";"adcd";"eddd";"ah";"ai";"aj";"ajkk"};

第六步

  //排序

  array = radix_sort(array )

第七步

  //输出结果

  for(i=1;#array;1){

  io.print( array[i] )

  }

  execute("pause") //按任意键继续

  io.close();//关闭控制台

声明:此文信息来源于网络,登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:fendou3451@163.com
标签:

  • 关注微信
上一篇:基数
下一篇:小坡的生日

相关文章