zoukankan      html  css  js  c++  java
  • 基数排序 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+="
    ";
     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。没有对前驱结点进行擦屁股操作。

  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/TQCAI/p/7653310.html
Copyright © 2011-2022 走看看