基数排序 RadixSort

Posted TQCAI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基数排序 RadixSort相关的知识,希望对你有一定的参考价值。

今晚看了一篇阅读,跑了会步,闲来无事又看起了严奶奶的数据结构,发现基数排序很有意思,用一种多关键字的思想,在基数较少的情况下可以取得较好的效果。

书中的讲解通俗易懂(但是严奶奶的代码我是看不懂的),我一下子就看懂了。立即打开电脑开始练习。

学习链接:最快最简单的排序——桶排序(超萌的漫画,非常容易理解)、基数排序排序算法系列:基数排序

今天编的很爽,调试的也很爽。只debug了三次,就没虫了。一个虫比较智障,是我发昏了。还有一个虫是在【定位到链表尾部】这个操作出现了逻辑盲区,一个虫是在【构造基数链表】是没有对先驱节点进行擦屁股操作,导致后期处理死循环。

唯一遗憾的是这个测试代码只能对不含负数的测试数据进行排序,如果包含了负数,radix数组所表示的基数肯定不是0~9了,而是,-9~9,一大堆东西都要改。


Java代码:

  1 public class Main {
  2 
  3     public static void main(String[] args) {
  4         int []nums={3,2,4,6,7,1,3,11,100,1000,1,20};
  5         RadixSort sort=new RadixSort(nums);
  6         System.out.print(sort);
  7     }
  8 }
  9 
 10 class RadixSort{
 11     int [] sortAns;
 12     class LinkedNums{
 13         int num=0;
 14         LinkedNums next=null;
 15     }
 16     LinkedNums first=new LinkedNums();
 17     LinkedNums radix[]=new LinkedNums[10];//0~9
 18      public String toString(){
 19          int i;
 20          String str=new String("");
 21          for(i=0;i<sortAns.length;i++) str+=String.valueOf(sortAns[i])+" ";
 22          str+="\\n";
 23          return str;
 24      }
 25      private void FormLinkedNums(int [] nums){
 26          int i;
 27          int len=nums.length;
 28          LinkedNums point=first;
 29          point.num=nums[0];
 30          for(i=1;i<len;i++){
 31              LinkedNums node=new LinkedNums();
 32              point.next=node;
 33              point=point.next;
 34              point.num=nums[i];
 35          }
 36      }
 37      private int GetInNum(int num,int rank){
 38          return
 39          (num%((int)Math.pow(10.0, (double)rank)))//运算得到当前取出的数
 40          /
 41          ((int)Math.pow(10.0, (double)(rank-1)));
 42      }
 43      private int GetMaxLenInArr(int [] nums){
 44          int i;
 45          int max=0;
 46          for(i=0;i<nums.length;i++){
 47              int len=String.valueOf(nums[i]).length();
 48              if(len>max) max=len;
 49          }
 50          return max;
 51      }
 52      RadixSort(int [] nums){
 53          int i,j;
 54          int len=nums.length;
 55          for(i=0;i<=9;i++) radix[i]=null;//对radix进行初始化
 56          FormLinkedNums(nums);
 57          int rank=1;//首先进行x%10的运算,再进行(x%100)/10的运算,再进行(x%1000)/100的运算
 58          int cirNum=GetMaxLenInArr(nums);
 59          for(j=0;j<cirNum;j++){
 60              LinkedNums point=first;
 61              while(point!=null){
 62                  int num=GetInNum(point.num,rank);
 63                  if(radix[num]==null){//基数数组没有勾链
 64                      radix[num]=point;
 65                  }else{
 66                      LinkedNums local=radix[num];
 67                      while(local.next!=null) local=local.next;    //【1】
 68                      local.next=point;//在这里进行勾链是不会破坏程序运行的。因为local的下标比point小。破坏local的后继关系没有影响
 69                  }
 70                  LinkedNums pre=point;//【2】
 71                  point=point.next;
 72                  pre.next=null;        //【2】
 73              }
 74              //基数数组勾链完毕。重新构造链表。
 75              //首先给first赋值。
 76              boolean isLinkedFirst=false;
 77              point=null;
 78              for(i=0;i<=9;i++){
 79                  if(radix[i]!=null){
 80                      LinkedNums local=radix[i];
 81                      if(! isLinkedFirst){
 82                          first=local;
 83                          isLinkedFirst=true;
 84                          point=first;
 85                          local=local.next;
 86                      }
 87                      while(local!=null){
 88                          point.next=local;
 89                          point=point.next;
 90                          local=local.next;
 91                      }
 92                  }
 93              }
 94              for(i=0;i<=9;i++) radix[i]=null;//对radix进行初始化
 95              rank++;//阶数递增
 96          }
 97          //将链表写入结果数组。
 98          sortAns=new int[len];
 99          i=0;
100          while(first!=null){
101              sortAns[i++]=first.num;
102              first=first.next;
103          }
104      }
105 }

逻辑盲区总结:

【1】:line 67。将 local.next!=null 写成了 local!=null ,导致空指针错误。

【2】:line 70、72。没有对前驱结点进行擦屁股操作。

 

以上是关于基数排序 RadixSort的主要内容,如果未能解决你的问题,请参考以下文章

小白初识 - 基数排序(RadixSort)

[硕.Love Python] RadixSort(基数排序)

基数排序:基数排序中的“组”是啥意思?

排序算法----基数排序(RadixSort(L))单链表智能版本

排序算法----基数排序(RadixSort(L,max))单链表版本

RadixSort 算法运行时间