基數排序法

2021-10-21 17:05:27 字數 3582 閱讀 2421

基數排序的發明可以追溯到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,...