缅怀初学 C 时大学时光。用 C 模拟的基数排序。
时间复杂度 O(d*n),d 为不同数字数目,n 为待排元素个数。
分为: MSD(most significant digit) 和 LSD(least significant digit)两种方法。
MSD:从最高级别的 key 开始排序,每趟排序将所有元素分成 d 堆。
LSD: 从最低级别的 key 开始排序,所有元素一起排序,直到有序。
我这里用 C 实现 LSD 的程序如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define BASE_NUM 10 typedef struct Node { int v; Node *next; } LinkList; LinkList *list[BASE_NUM] = {0}; /* 1. if use an array of integer ,?will be more convenient; 2. v also can save the index */ void release(LinkList *Base[]) { int i; Node *pre = NULL; for(i = 0; i < BASE_NUM; ++i) { if(list[i] == NULL) continue; do { pre = list[i]; list[i] = list[i]->next; free(pre); }while(Base[i] != NULL); } } void radixSort(int data[], int length) { Node *p[BASE_NUM] = {0}; int maxData = 0, temV = 1, base_id; int i, k, sortTime = 1; for(i = 0; i < length; ++i) // get the max value. maxData = data[i] > maxData ? data[i] : maxData; while(maxData >= temV) // Allocation { for(i = 0; i < length; ++i){ base_id = data[i] / temV % 10; Node *s = (Node*)malloc(sizeof(Node)); s->v = data[i]; s->next = NULL; if(list[base_id] == NULL){ list[base_id] = s; p[base_id] = list[base_id]; }else{ p[base_id]->next = s; p[base_id] = p[base_id]->next; } } k = 0; for(i = 0; i < BASE_NUM; ++i) // take back { p[i] = list[i]; while(p[i] != NULL) { data[k++] = p[i]->v; p[i] = p[i]->next; } } printf("第 %d 趟后: ", sortTime++); // print current numbers for(i = 0; i < length; ++i) printf("%d ", data[i]); printf(" "); release(list); temV *= BASE_NUM; } } void init(int data[], int length) { /*srand(1);*/ for(int i = 0; i < length; ++i) data[i] = rand()%1000; } int main() { enum{ N = 10}; int numbers[N], i; init(numbers, N); printf("待排数据: "); for(i = 0; i < N; ++i) printf("%d ", numbers[i]); printf(" "); radixSort(numbers, N); printf("排序结果: "); for(i = 0; i < N; ++i) printf("%d ", numbers[i]); printf(" "); return 0; }