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。没有对前驱结点进行擦屁股操作。

  • 相关阅读:
    【Python】Visual Studio Code 安装&&使用 hello python~~~~
    linux系统644、755、777权限详解
    python对象销毁(垃圾回收)
    linux .bashrc文件修改和生效
    Python学习笔记(20)-文件和文件夹的移动、复制、删除、重命名
    HDU 4635 Strongly connected(强连通)经典
    推荐一款免费的SQLsever的备份软件sqlBackupAndFtp
    Objective-C基础笔记(6)Block
    iOS开发UI篇—懒载入
    关于Adapter对数据库的查询、删除操作
  • 原文地址:https://www.cnblogs.com/TQCAI/p/7653310.html
Copyright © 2011-2022 走看看