基數排序也是穩定的內排序。
因爲它的實現是基於內部使用了穩定的排序實現的所以基數排序整體是穩定的,而且時間複雜度爲O(n)。
舉個例子:
現在我們將一些3(多)位數排序,如果你說直接判斷就好的話,那你就太天真了,因爲那就又變成看O(nlgn)或者O(n²)。
如何能降低時間複雜度變成O(n) 呢?
那就要使用線性時間的排序了,正如上篇的計數排序。
基數排序 利用的是計數排序進行排序的。因爲計數排序是穩定的排序,即排序後的大小順序 會與 上一輪的排序順序結果一致。
再舉個例子:
排序前 | 第一遍排序後 | 第二遍排序後 | 第三遍排序後 | 排序的結果 |
331 | 420 | 410 | 315 | 315 |
315 | 410 | 315 | 331 | 331 |
420 | 331 | 420 | 410 | 410 |
410 | 315 | 331 | 420 | 420 |
請看:
1、 第二次排序後 你會發現 :315 一直是在 331 下面 ;410 一直是在 420 下面。
2、 第三次排序後 就會整體有序了。
RadixSort(int [] a){
for i = 1 to n-1 // 位數 從個位到最高位 依次實行 排序
countingSort(b[i]) //計數排序
}
附上算法代碼:
public class RadixSort {
public static int[] countingSort(int[] a, int[] s, int p, int k) {
int num = a.length;
int[] medium = new int[k];
int[] result = new int[k];
for (int i = 0; i < num; i++) {
result[i] = 0;
medium[i] = 0;
}
for (int i = 0; i < num; i++) {
if((s[i]/p)%10 == a[i]){
medium[a[i]] +=1;
}
}
for (int i = 1; i < k; i++) {
medium[i] += medium[i - 1];
}
for (int i = num - 1; i >= 0; i--) {
result[--medium[a[i]]] = s[i];
}
return result;
}
public static int [] RadixSort(int[] s){
int[] a = new int[s.length];
for (int n = 0; n < 3; n++) {
int p = (int)Math.pow(10,n);
for (int i = 0; i < s.length; i++) { //取得 每位的數字 進行後續排序
int x = s[i]/p;
a[i] = x % 10;
}
s = countingSort(a, s, p, 10); //10 每位數字的範圍
System.out.println("第 "+(n+1)+" 次");
for (int v : s) {
System.out.print(v + " ");
}
System.out.println();
}
return s;
}
public static void main(String[] args) {
int[] s = {232, 552, 227, 234, 553, 228, 236, 229, 215, 222};
for (int v : s) {
System.out.print(v + " ");
}
System.out.println();
s=RadixSort(s);
System.out.println("最終結果:");
for (int v : s) {
System.out.print(v + " ");
}
}
}
歡迎討論……