核心算法:
void RadixPass(RcdType rcd[], RcdType rcd1[], int n, int i, int count[], int pos[], int radix)
{
//对数组rcd中记录关键字的第i位计数,计算得到起始位置数组pos
//按照起始位置数组pos将rcd中的记录复制到数组rcd1中
int k, j;
for (k = 1; k <= n; k++)
count[rcd[k].keys[i]] ++;
pos[0] = 1; //1为计数起始点,关键字0是第一个
for (j = 1; j < radix; j++)
pos[j] = count[j - 1] + pos[j - 1];
for (k = 1; k <= n; k++) {
j = rcd[k].keys[i]; //关键字
rcd1[pos[j]++] = rcd[k]; //复制记录
}
}
Status RadixSort(RcdList &L)
{
RcdType *rcd1;
int *count, *pos; //count记统计第i个记录的关键字的各种取值 pos统计值为j的关键字的起始位置
count = (int *)malloc(L.radix * sizeof(int));
pos = (int *)malloc(L.radix * sizeof(int));
rcd1 = (RcdType *)malloc((L.length + 1)*sizeof(RcdType));
if (NULL == count || NULL == pos || NULL == rcd1) return ERROR;
int i = 0, j;
while (i < L.digitNum) {
for (j = 0; j < L.radix; j++)
count[j] = 0;
/*每趟基数排序 i++*/
if (0 == i % 2) //对rcd进行一趟基数排序
RadixPass(L.rcd, rcd1, L.length, i++, count, pos, L.radix);
else RadixPass(rcd1, L.rcd, L.length, i++, count, pos, L.radix); //对rcd1进行一趟基数排序
}
/*奇数复制回去*/
if (1 == L.digitNum % 2) {
for (j = 1; j <= L.length; j++)
L.rcd[j] = rcd1[j];
}
free(count);
free(pos);
free(rcd1);
return OK;
}
测试代码:
data_structure.h
#ifndef DATA_STRUCTURE_H
#define DATA_STRUCTURE_H
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int KeyType;
typedef struct
{
KeyType *keys;
//others members;
}RcdType;
typedef struct
{
RcdType *rcd;
int length; //顺序表长度
int size; //顺序表容量
int digitNum; //关键字位数
int radix; //关键字基数
}RcdList;
#endif
#include <stdio.h>
#include <stdlib.h>
#include "data_structure.h"
Status InitRcdList(RcdList &L, int digitNum, int radix, KeyType key[], int n)
{
L.rcd = (RcdType*)malloc((n + 1)*sizeof(RcdType));
if (L.rcd == NULL) return ERROR;
L.digitNum = digitNum;
L.radix = radix;
L.length = n;
L.size = n + 1;
int i, j;
for (i = 1; i <= L.length; i++) {
L.rcd[i].keys = (KeyType*)malloc(L.digitNum * sizeof(KeyType));
if (L.rcd[i].keys == NULL) return ERROR;
}
KeyType tKey;
for (i = 1; i <= L.length; i++) {
tKey = key[i - 1];
for (j = 0; j < L.digitNum; j++) {
L.rcd[i].keys[j] = tKey % L.radix;
tKey /= L.radix;
}
}
return OK;
}
void PrintRcdList(RcdList L)
{
int i, j;
for (i = 1; i <= L.length; i++) {
for (j = 0; j < L.digitNum; j++)
printf("%d ", L.rcd[i].keys[j]);
printf("\n");
}
}
int main()
{
RcdList list;
KeyType key[8] = { 337, 332, 132, 267, 262, 164, 260, 167 };
InitRcdList(list, 3, 10, key, 8);
PrintRcdList(list);
printf("\nRadixSort:\n");
RadixSort(list);
PrintRcdList(list);
system("pasue");
return 0;
}
基数排序算法的时间复杂度为O(mn),其实n是记录数,m是关键字个数,通常m远小于n,时间复杂度可视作O(n),空间复杂度为O(n) 。