十大經典排序演算法(十、基數排序)
阿新 • • 發佈:2020-12-29
基數排序是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。
基數排序有兩種方法:
這三種排序演算法都利用了桶的概念,但對桶的使用方法上有明顯差異:
- 基數排序:根據鍵值的每位數字來分配桶;
- 計數排序:每個桶只儲存單一鍵值;
- 桶排序:每個桶儲存一定範圍的數值;
JavaScript
1 ar counter = []; 2 function radixSort(arr, maxDigit) { 3 var mod = 10; 4 var dev = 1; 5 for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {6 for(var j = 0; j < arr.length; j++) { 7 var bucket = parseInt((arr[j] % mod) / dev); 8 if(counter[bucket]==null) { 9 counter[bucket] = []; 10 } 11 counter[bucket].push(arr[j]); 12 } 13 var pos = 0; 14 for(var j = 0; j < counter.length; j++) { 15 var value = null; 16 if(counter[j]!=null) { 17 while ((value = counter[j].shift()) != null) { 18 arr[pos++] = value; 19 } 20 } 21 } 22 } 23 return arr; 24}
C語言
1 #include<stdio.h> 2 #define MAX 20 3 //#define SHOWPASS 4 #define BASE 10 5 6 void print(int *a, int n) { 7 int i; 8 for (i = 0; i < n; i++) { 9 printf("%d\t", a[i]); 10 } 11 } 12 13 void radixsort(int *a, int n) { 14 int i, b[MAX], m = a[0], exp = 1; 15 16 for (i = 1; i < n; i++) { 17 if (a[i] > m) { 18 m = a[i]; 19 } 20 } 21 22 while (m / exp > 0) { 23 int bucket[BASE] = { 0 }; 24 25 for (i = 0; i < n; i++) { 26 bucket[(a[i] / exp) % BASE]++; 27 } 28 29 for (i = 1; i < BASE; i++) { 30 bucket[i] += bucket[i - 1]; 31 } 32 33 for (i = n - 1; i >= 0; i--) { 34 b[--bucket[(a[i] / exp) % BASE]] = a[i]; 35 } 36 37 for (i = 0; i < n; i++) { 38 a[i] = b[i]; 39 } 40 41 exp *= BASE; 42 43 #ifdef SHOWPASS 44 printf("\nPASS : "); 45 print(a, n); 46 #endif 47 } 48 } 49 50 int main() { 51 int arr[MAX]; 52 int i, n; 53 54 printf("Enter total elements (n <= %d) : ", MAX); 55 scanf("%d", &n); 56 n = n < MAX ? n : MAX; 57 58 printf("Enter %d Elements : ", n); 59 for (i = 0; i < n; i++) { 60 scanf("%d", &arr[i]); 61 } 62 63 printf("\nARRAY : "); 64 print(&arr[0], n); 65 66 radixsort(&arr[0], n); 67 68 printf("\nSORTED : "); 69 print(&arr[0], n); 70 printf("\n"); 71 72 return 0; 73 }
C++
1 int maxbit(int data[], int n) //輔助函式,求資料的最大位數 2 { 3 int maxData = data[0]; ///< 最大數 4 /// 先求出最大數,再求其位數,這樣有原先依次每個數判斷其位數,稍微優化點。 5 for (int i = 1; i < n; ++i) 6 { 7 if (maxData < data[i]) 8 maxData = data[i]; 9 } 10 int d = 1; 11 int p = 10; 12 while (maxData >= p) 13 { 14 //p *= 10; // Maybe overflow 15 maxData /= 10; 16 ++d; 17 } 18 return d; 19 /* int d = 1; //儲存最大的位數 20 int p = 10; 21 for(int i = 0; i < n; ++i) 22 { 23 while(data[i] >= p) 24 { 25 p *= 10; 26 ++d; 27 } 28 } 29 return d;*/ 30 } 31 void radixsort(int data[], int n) //基數排序 32 { 33 int d = maxbit(data, n); 34 int *tmp = new int[n]; 35 int *count = new int[10]; //計數器 36 int i, j, k; 37 int radix = 1; 38 for(i = 1; i <= d; i++) //進行d次排序 39 { 40 for(j = 0; j < 10; j++) 41 count[j] = 0; //每次分配前清空計數器 42 for(j = 0; j < n; j++) 43 { 44 k = (data[j] / radix) % 10; //統計每個桶中的記錄數 45 count[k]++; 46 } 47 for(j = 1; j < 10; j++) 48 count[j] = count[j - 1] + count[j]; //將tmp中的位置依次分配給每個桶 49 for(j = n - 1; j >= 0; j--) //將所有桶中記錄依次收集到tmp中 50 { 51 k = (data[j] / radix) % 10; 52 tmp[count[k] - 1] = data[j]; 53 count[k]--; 54 } 55 for(j = 0; j < n; j++) //將臨時陣列的內容複製到data中 56 data[j] = tmp[j]; 57 radix = radix * 10; 58 } 59 delete []tmp; 60 delete []count; 61 }