链式基数排序法
一、性能分析:
若有n条记录,记录最多含有a个关键字,每个关键字的基数取值范围为b个值,则:
1.平均时间复杂度 = O(a(n + b))
2.空间复杂度:O(ab)
二、实现:
1 #define INDEX 10 //关键字基数,此时是十进制整数的基数 2 #define KEYNUM 2 //最大关键字个数 3 4 typedef struct Node { 5 int data; 6 struct Node* next; 7 }Node; 8 9 struct { 10 Node* head; 11 }L[INDEX];//指针数组L 12 13 void RadixSort(int a[], int n) { 14 int i, j; 15 for (i = 0; i < KEYNUM; ++i) { 16 for (j = 0; j < INDEX; ++j) { //重置链表L 17 L[j].head = NULL; 18 } 19 Distribute(a, i, n); //分配数组a中元素的第i项到链表L中 20 Collect(a); //收集链表L中元素到数组a中 21 } 22 } 23 24 void Distribute(int a[], int m, int n) { //记录的第m项,元素总数n 25 int i, k; 26 Node *P, *F; 27 for (i = 1; i < n; ++i) { 28 k = Digit(a[i], m); //k为a[i]的第m项 29 P = (Node*)calloc(1, sizeof(Node)); //把记录a[i]备份到结点P中 30 P->data = a[i]; 31 if (L[k].head) { //若链表该域的头指针存在,则链接到该域的尾部 32 for (F = L[k].head; F->next; F = F->next); 33 F->next = P; 34 } 35 else { //否则直接插入结点P 36 L[k].head = P; 37 } 38 } 39 } 40 41 void Collect(int a[]) { 42 int i = 0, j = 1; 43 Node* P; 44 while (i < INDEX) { 45 for (P = L[i++].head; P; P = P->next) { //从小到大把链表元素存入数组a中 46 a[j++] = P->data; 47 } 48 } 49 } 50 51 int Digit(int num, int m) { //返回数num中的倒数第m项 52 while (m--) { 53 num /= INDEX; 54 } 55 return num % INDEX; 56 }
三、源代码

1 //在 Microsoft Visual Studio Community 2022 环境测试通过 2 #define _CRT_SECURE_NO_WARNINGS 3 #include <stdio.h> 4 #include <stdlib.h> 5 #define INDEX 10 //关键字基数,此时是十进制整数的基数 6 #define KEYNUM 2 //最大关键字个数 7 8 typedef struct Node { 9 int data; 10 struct Node* next; 11 }Node; 12 13 struct { 14 Node* head; 15 }L[INDEX];//指针数组L 16 17 int Digit(int num, int m) { //返回数num中的倒数第m项 18 while (m--) { 19 num /= INDEX; 20 } 21 return num % INDEX; 22 } 23 24 void Distribute(int a[], int m, int n) { //记录的第m项,元素总数n 25 int i, k; 26 Node *P, *F; 27 for (i = 1; i < n; ++i) { 28 k = Digit(a[i], m); //k为a[i]的第m项 29 P = (Node*)calloc(1, sizeof(Node)); //把记录a[i]备份到结点P中 30 P->data = a[i]; 31 if (L[k].head) { //若链表该域的头指针存在,则链接到该域的尾部 32 for (F = L[k].head; F->next; F = F->next); 33 F->next = P; 34 } 35 else { //否则直接插入结点P 36 L[k].head = P; 37 } 38 } 39 } 40 41 void Collect(int a[]) { 42 int i = 0, j = 1; 43 Node* P; 44 while (i < INDEX) { 45 for (P = L[i++].head; P; P = P->next) { //从小到大把链表元素存入数组a中 46 a[j++] = P->data; 47 } 48 } 49 } 50 51 void RadixSort(int a[], int n) { 52 int i, j; 53 for (i = 0; i < KEYNUM; ++i) { 54 for (j = 0; j < INDEX; ++j) { //重置链表L 55 L[j].head = NULL; 56 } 57 Distribute(a, i, n); //分配数组a中元素的第i项到链表L中 58 Collect(a); //收集链表L中元素到数组a中 59 } 60 } 61 62 int main(void) { 63 int i = 1, a[11] = { 0, 82, 31, 95, 63, 44, 32, 54, 12, 11, 0 };//a[0]哨兵位 64 RadixSort(a, 11); 65 while (i < 11) { 66 printf("%d ", a[i++]); 67 } 68 }