1. 程式人生 > >基數排序 RadixSort

基數排序 RadixSort

col 如果 href private pos 算法系列 rgs 出現 oid

今晚看了一篇閱讀,跑了會步,閑來無事又看起了嚴奶奶的數據結構,發現基數排序很有意思,用一種多關鍵字的思想,在基數較少的情況下可以取得較好的效果。

書中的講解通俗易懂(但是嚴奶奶的代碼我是看不懂的),我一下子就看懂了。立即打開電腦開始練習。

學習鏈接:最快最簡單的排序——桶排序(超萌的漫畫,非常容易理解)、基數排序、排序算法系列:基數排序

今天編的很爽,調試的也很爽。只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