來源360百科:html
基數排序(radix sort)屬於"分配式排序"(distribution sort),又稱"桶子法"(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些"桶"中,藉以達到排序的做用,基數排序法是屬於穩定性的排序,其時間複雜度爲O (nlog(r)m),其中r爲所採起的基數,而m爲堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。數組
從上面的簡單介紹,是並不瞭解基數排序是怎麼弄的~基數排序不一樣與其餘的7種排序,其餘7種排序本質上都是按照交換或者比較來進行排序,可是基數排序並非,它是按照分配,回收(分配到不一樣的位置上,而後回收)..不斷分配..回收來進行排序,直到有序..微信
聽上去好像很高大上,很難的樣子,其實否則。基數排序挺簡單的,下面我就來看一下基數排序的流程....網絡
咱們有9個桶,將數組的數字按照數值分配桶中:測試
ps:圖片來源於網絡,侵刪spa
上面咱們發現:若是將桶按順序進行回收,那麼咱們的排序就完成了~code
但是,通常咱們的數組元素都不只僅是個位數的數字的呀,那麼高位數的數字又怎麼弄呢??好比:23,44,511,6234這些高位數..htm
其實也是同樣的:blog
ps:圖片來源於網絡,侵刪排序
機智的同窗可能就會發現了,關於這個桶咱們能夠用二維數組來進行存放。
10個桶子就是10列,若是分配時有的數字相同的話,那麼就弄成多行~
首先咱們有如下這個數組:
int[] arrays = {6, 4322, 432, 344, 55 };
如今咱們有10個桶子,每一個桶子下能裝載arrays.length
個數字..
int[][] buckets = new int[arrays.length][10];
效果以下:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
將數組的每一個個位數進行分配到不一樣的桶子上:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | |||||||||
4322 | |||||||||
432 | |||||||||
344 | |||||||||
55 |
分配完以後,咱們按照順序來進行回收:獲得的結果應該是這樣子的:{4322,432,344,55,6}
將數組的每一個十位數進行分配到不一樣的桶子上(像6這樣的數,往前邊補0):
因而咱們能夠獲得這樣的排序:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | |||||||||
4322 | |||||||||
432 | |||||||||
344 | |||||||||
55 |
分配完以後,咱們按照順序來進行回收:獲得的結果應該是這樣子的:{6,4322,432,344,55}
將數組的每一個百位數進行分配到不一樣的桶子上(像六、55這樣的數,往前邊補0):
因而咱們能夠獲得這樣的排序:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | |||||||||
55 | 4322 | ||||||||
432 | |||||||||
344 | |||||||||
分配完以後,咱們按照順序來進行回收:獲得的結果應該是這樣子的:{6,55,4322,344,432}
將數組的每一個百位數進行分配到不一樣的桶子上(像六、55,344,432這樣的數,往前邊補0):
因而咱們能夠獲得這樣的排序:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | |||||||||
55 | |||||||||
344 | |||||||||
432 | |||||||||
4322 |
分配完以後,咱們按照順序來進行回收:獲得的結果應該是這樣子的:{6,55,344,432,4322}
此時咱們的數組就已經能夠排好序了~~~過程就是這樣子,其實不難就只有兩個步驟:
咱們的基數排序是按照個、10、百、千位...來進行存放的。前面的演示是已經知道數組元素的數據的狀況下來進行存放,可是通常咱們是不去理會數組內元素的值的。那若是位數不少(萬位)或者都是個位數,這個條件咱們怎麼去處理呢?
咱們能夠這樣作:先求出數組最大的值,而後不斷/10,只要它能大於0,那麼它的位數還有~:
這個我在前面寫遞歸的時候就有這個代碼了,我就直接搬去遞歸的代碼過來了,順便複習一哈吧:
/** * 遞歸,找出數組最大的值 * @param arrays 數組 * @param L 左邊界,第一個數 * @param R 右邊界,數組的長度 * @return */ public static int findMax(int[] arrays, int L, int R) { //若是該數組只有一個數,那麼最大的就是該數組第一個值了 if (L == R) { return arrays[L]; } else { int a = arrays[L]; int b = findMax(arrays, L + 1, R);//找出總體的最大值 if (a > b) { return a; } else { return b; } }
public static void radixSort(int[] arrays) { int max = findMax(arrays, 0, arrays.length - 1); //須要遍歷的次數由數組最大值的位數來決定 for (int i = 1; max / i > 0; i = i * 10) { int[][] buckets = new int[arrays.length][10]; //獲取每一位數字(個、10、百、千位...分配到桶子裏) for (int j = 0; j < arrays.length; j++) { int num = (arrays[j] / i) % 10; //將其放入桶子裏 buckets[j][num] = arrays[j]; } //回收桶子裏的元素 int k = 0; //有10個桶子 for (int j = 0; j < 10; j++) { //對每一個桶子裏的元素進行回收 for (int l = 0; l < arrays.length ; l++) { //若是桶子裏面有元素就回收(數據初始化會爲0) if (buckets[l][j] != 0) { arrays[k++] = buckets[l][j]; } } } } }
搞了一堆數測試了一哈:
基數排序(桶排序)要理解起來並不困難,不過值得注意的是:基數排序對有負數和0的數列難以進行排序
基數排序的要點就兩個:
參考資料:
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y