基數排序的發明可以追溯到2023年赫爾曼·何樂禮在打孔卡片製表機(tabulation machine)上的貢獻。基數排序(radix sort)屬於「分配式排序」(distribution sort),又稱「桶子法」(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些「桶」中,藉以達到排序的作用,基數排序法是屬於穩定性的排序,其時間複雜度為o (nlog(r)m),其中r為所採取的基數,而m為堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。
它是這樣實現的:將所有待比較數值(正整數)統一為同樣的數字長度,數字較短的數前面補零。然後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以後, 數列就變成乙個有序序列。基數排序的方式可以採用lsd(least significant digital)或msd(most significant digital),lsd的排序方式由鍵值的最右邊開始,而msd則相反,由鍵值的最左邊開始。
最高位優先(most significant digit first)法,簡稱msd法:先按k1排序分組,同一組中記錄,關鍵碼k1相等,再對各組按k2排序分成子組,之後,對後面的關鍵碼繼續這樣的排序分組,直到按最次位關鍵碼kd對各子組排序後。再將各組連線起來,便得到乙個有序序列。
最低位優先(least significant digit first)法,簡稱lsd法:先從kd開始排序,再對kd-1進行排序,依次重複,直到對k1排序後便得到乙個有序序列。
陣列: ,設定編號0到9,陣列元素按個位 十位 百位 千位等從最右邊開始。
第一步個位開始,如下表所示:編號0
1234
5678
9元素081
2273
145500
2839
9365
43接下來將以上桶子中的數值重新串接起來,成為以下的數列:81, 22, 73, 93, 43, 14, 55, 65, 28, 39
第二步十位開始,如下表所示:編號0
1234
5678
9元素014
2239
4355
6573
8193
28接下來將以上桶子中的數值重新串接起來,成為以下的數列:14, 22, 28, 39, 43, 55, 65, 73, 81, 93
至此,陣列的元素排序完畢,得到後的陣列:
若元素有個十百千萬等高位數字,則持續進行以上的動作直至最高位數為止。
第一種方法:
/**
* 實現的:將所有待比較數值(正整數)統一為同樣的數字長度,數字較短的數前面補零。然後,從最低位開始,依次進行一次排序。
* 這樣從最低位排序一直到最高位排序完成以後, 數列就變成乙個有序序列。
** 實現:1、定義二維陣列,根據元素的位數 存元素的位置
* 2、根據 步驟1 的結果,重新遍歷,排序新的元素位置
* 3、根據 步驟2 的結果,重新遍歷,依次類推,最後得到想要的 排序陣列
**
*/@test
public void test();
// 數字的位數
int d = 3;
int k = 0;
int n = 1;
//控制鍵值排序依據在哪一位
int m = 1;
//陣列的第一維表示可能的餘數0-9,第二維表示出現的次數
int temp = new int[10][number.length];
//陣列order[i]用來表示該位是i的數的個數
int order = new int[10];
// 遍歷數字的位數
while(m <= d)
// 遍歷 0-9 的元素
for(int i = 0; i < 10; i++)
}// 位數沒有出現元素,則預設為 0
order[i] = 0;
}system.out.println(arrays.tostring(number));
// 個位為 1,十位為 10,百位為 100 .。。
n *= 10;
// 元素下標從 0 開始
k = 0;
// 元素的位數增加
m++;
}// 獲取排序後的陣列
for(int i = 0; i < number.length; i++)
}
第二種方法:
@test
public void test2();
int maxdigit = getmaxdigit(arr);
// 位數,個位時取 10 ,十位時 取 100,百位時取 1000
int mod = 10;
// 位置計算,如個位 十位 百位 千位
int dev = 1;
// for 迴圈,遍歷位數如 個位 十位 百位 。。。
for (int i = 0; i < maxdigit; i++, dev *= 10, mod *= 10)
int pos = 0;
for (int bucket : counter) }}
system.out.println("基數排序:"+arrays.tostring(arr));
}/**
* 獲取最高位數
*/private int getmaxdigit(int arr)
/*** 獲取陣列元素種最大的值
* @param arr
* @return
*/private int getmaxvalue(int arr)
}return maxvalue;
}/**
* 獲取陣列中元素做多的位數如 100 三位
* @param num
* @return
*/protected int getnumlenght(long num)
int lenght = 0;
// 利用 /= 取整數,最後的結果為 0,結束迴圈
for (long temp = num; temp != 0; temp /= 10)
// 返回 位數
return lenght;
}/**
* 自動擴容,並儲存資料
** @param arr
* @param value
*/arr = arrays.copyof(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
第一種方法比較好理解,利用二維陣列儲存資料;第二種方法比較完善比較細膩,但counter[bucket]的處理比較抽象。 基數排序法
摘要 1 基數排序法是建立在桶式排序的基礎之上,而桶式排序的缺點就是不方便計算數值很大的陣列 元素個數不一定多 利用基數排序可以解決這個問題 2 基數排序的基本思想是將元素的每一位都拿出來進行比較,比較的順序是從低位到高位。第一次比較之後,再將比較過的資料取出下一位進行比較 注意 比較的是某一位 或...
基數排序法
基數排序是一種常見的演算法,雖然在各個資料結構教材中都能看到,但在面試或筆試中卻很少遇到。雖然知道基數排序的原理,但從未寫過它的實現演算法,最近看了字尾陣列中用到了基數排序,又仔細研究了下,很有收穫。基數排序不同於其他的排序演算法,它不是基於比較的演算法。基數排序是一種借助多關鍵字排序的思想對單邏輯...
基數排序法(Java實現)
class demo 呼叫基數排序函式 lsd radixsort arr,3 輸出排序後的陣列 for int i 0 i arr是要排序的陣列,max是陣列中最大的數有幾位 public static void lsd radixsort int arr,int max 分別統計第k位是0,1,...