陣列排序-基數排序(Radix Sort)
阿新 • • 發佈:2021-01-08
概念:
基數排序屬於“分配式排序”,又稱“桶子法”,顧名思義,它是透過鍵值的部分資訊,將要排序的元素分配至某些“桶”中,即以達到排序的作用,基數排序法是屬於穩定性的排序,其時間複雜度為O(nlog(r)m),其中r為所採取的基數,而m為堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。
實現方法:
最高位優先(Most Significant Digit first)法,簡稱MSD法:先按k1排序分組,同一組中記錄,關鍵碼k1相等,再對各組按k2排序分成子組,之後,對後面的關鍵碼繼續這樣的排序分組,直到按最次位關鍵碼kd對各子組排序後。再將各組連線起來,便起到一個有序序列。
最低位優先(Least Significance Digit first)法,簡稱LSD法:先從kd開始排序,再對kd-1進行排序,依次重複,直到對k1排序後便得到一個有序序列。
實現原理:
基數排序的發明可以追溯導1887年,赫爾曼·何樂禮在打孔卡片製表機(Tabulation Machine)上的貢獻。它是這樣實現的:將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。然後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以後,數列就變成一個有序序列。
基數排序的方式可以採用LSD(Least significance digital)或MSD(Most significance digital),LSD的排序方式由鍵值的最右邊開始,而MSD則相反,由鍵值的最左邊開始。
示例:
package com.cnblogs.lxj.testarraysort; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @packageName: com.cnblogs.lxj.testarraysort * @className: RadixSort * @description: 測試基數排序 * @author: liuxiaojiang * @date: 2021/1/8 */ public class RadixSort { public static void main(String[] args) { int[] a = new int[]{321,1,10,60,577,743,127}; printArray(a); radixSortOne(a,10,3); printArray(a); } /** * @description: 基數排序方法(1) * @author: liuxiaojiang * @date: 2021/1/8 * @param a: 代表陣列 * @param radix: 代表基數 * @param d: 代表排序元素的位數 * @return: void **/ public static void radixSortOne(int[] a,int radix,int d){ List<List<Integer>> ts = new ArrayList<List<Integer>>(); int rate = 1; for(int i = 0;i < radix;i++){ List<Integer> t = new ArrayList<Integer>(); ts.add(t); } for(int i = 0;i < d;i++){ for(int j = 0;j < radix;j++){ List<Integer> t = ts.get(j); t.clear(); } for(int j = 0;j < a.length;j++){ int subKey = (a[j]/rate) % radix; List<Integer> t = ts.get(subKey); t.add(a[j]); } int count = 0; for(int j = 0; j < radix;j++){ List<Integer> t = ts.get(j); for(int k = 0;k < t.size();k++){ a[count++] = t.get(k); } } rate *= radix; System.out.print("第"+(i+1)+"次:"); printArray(a); } } /** * @description: 基數排序方法(2) * @author: liuxiaojiang * @date: 2021/1/8 * @param array: 代表陣列 * @param radix: 代表基數 * @param d: 代表排序元素的位數 * @return: void **/ public static void radixSortTwo(int[] array,int radix,int d){ int[] tempArray = new int[array.length]; int[] count = new int[radix]; int rate = 1; for(int i = 0;i < d;i++){ Arrays.fill(count,0); System.arraycopy(array,0,tempArray,0,array.length); for(int j = 0;j < array.length;j++){ int subKey = (tempArray[j] / rate) % radix; count[subKey]++; } for(int j = 1;j < radix;j++){ count[j] = count[j] + count[j - 1]; } for(int m = array.length - 1;m >= 0;m--){ int subKey = (tempArray[m] / rate) % radix; array[--count[subKey]] = tempArray[m]; } rate *= radix; System.out.print("第"+(i+1)+"次:"); printArray(array); } } /** * @description: 輸出方法 * @author: liuxiaojiang * @date: 2021/1/8 * @param array: 代表陣列 * @return: void **/ public static void printArray(int[] array){ for(int i : array){ System.out.print(i+" "); } System.out.println(); } }
執行結果:
321 1 10 60 577 743 127 //初始化
第1次:10 60 321 1 743 577 127
第2次:1 10 321 127 743 60 577
第3次:1 10 60 127 321 577 743
1 10 60 127 321 577 743 //最終結果