java 实现 常见排序算法(四)基数排序
大家好,我是烤鴨:????
???今天分享一下基礎排序算法之基數排序。
?
1.????基數排序:
原理:基數排序(radix sort)屬于“分配式排序”(distribution sort),又稱“桶子法”(bucket sort)或bin sort。
將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。然后,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以后, 數列就變成一個有序序列。
思路:
基數排序,即一個數位一個數位地進行排序,平常生活中我們經常使用的一種算法思想:如要對一個日期進行排序,日期中由年、月、日組成的,對于這個問題,我們經常使用的是先比較年份,如果相同再比較月份,如果還相同就比較日。
下面四個數進行排序:123、312、245、531
???個位?=>??十位?=>??百位
???531??????312??????123
? ?312? ? ??123? ? ??245
???123??????531??????312
???245??????245??????531
代碼實現:
/*** 基數排序* @param d* @param array* 時間復雜度 O的log2 N* 基數排序 運用二維數組來分別比較每一位,個位、十位、百位…* 輸入10個整數的數組*/private void radixSort(int d,int[] array){long nowTime = System.nanoTime();int n=1;//代表位數對應的數:1,10,100000...int k=0;//保存每一位排序后的結果用于下一位的排序輸入int[][] bucket=new int[10][array.length];//排序桶用于保存每次排序后的結果,這一位上排序結果相同的數字放在同一個桶里int[] num=new int[array.length];//用于保存每個桶里有多少個數字 ,最多為輸入數組長度while(n<=d){for(int e:array) //將數組array里的每個數字放在相應的桶里{int digit=(e/n)%10;bucket[digit][num[digit]]=e;num[digit]++;}for(int i=0;i<array.length;i++)//將前一個循環生成的桶里的數據覆蓋到原數組中用于保存這一位的排序結果{if(num[i]!=0)//這個桶里有數據,從上到下遍歷這個桶并將數據保存到原數組中{for(int j=0;j<num[i];j++){array[k]=bucket[i][j];k++;}}num[i]=0;//將桶里計數器置0,用于下一次位排序}n*=10;k=0;//將k置0,用于下一輪保存位排序結果}System.out.println("基數排序,花費時間(ms):" + ((System.nanoTime() - nowTime) / 1000000.0) + "ms");}基數排序是穩定算法,效率很高,其復雜度為O(nlog(r)m),其中r為所采取的基數,而m為堆數。但它只能用在整數的排序中,且需要借助一定的輔助空間。
上面的代碼適用有些局限在于對基數值選取:
int [] x = {25 ,11 ,22 ,34 ,15 ,44 ,76, 66, 100, 8 ,14, 20 ,2, 5 ,1 };比如這個數組,基數應該選3。附上一個選擇基數值的方法。
/*** 獲取基數排序中的基數* @param array* @return*/public int getRadixBasicNumber(int[] array){if(array == null && array.length ==0) {return 0;}int max =0;//1獲取最大的絕對值的數for(int i =0;i<array.length;i++) {if(Math.abs(max)<Math.abs(array[i])) {max = array[i];}}int times = 0;if(max<0) max = -max;//2求出最大的絕對值的數,是10的times次冪。while(max >0) {max = max/10;times ++;}return times;}?
耗時對比:
10W 條隨機 數據 運行如圖:
分別對比了基數排序,直插排序,希爾排序和快速排序。差距很明顯。
50W 條隨機 數據 運行如圖:
分別對比了基數排序,直插排序,希爾排序和快速排序。差距很明顯。
100W 條隨機 數據 運行如圖:
分別對比了基數排序,直插排序,希爾排序和快速排序。差距很明顯。
總結:
基數排序
優點:效率高。
缺點:占用內存大,只能對正整數排序(采用二維數組做桶時)
最壞時間復雜度:O(P(N+B))。
平均時間復雜度為:O(P(N+B))。
其中P是排序的趟數,N是要被排序元素的個數,B是桶數。
各種排序方法比較:
?
更多排序算法:
冒泡排序? ?:??https://blog.csdn.net/Angry_Mills/article/details/81057900
插入排序? ?:??https://blog.csdn.net/Angry_Mills/article/details/81208700
快速排序???:??https://blog.csdn.net/Angry_Mills/article/details/83339390
總結
以上是生活随笔為你收集整理的java 实现 常见排序算法(四)基数排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOS 上传ipa文件失败
- 下一篇: axure8 Mac破解版+汉化包