基数排序是个很有特点的排序方法。它不关注整个数据,而是数据的每一位。按每一位排完序之后,最终的排序序列也就出来了。
#include <iostream>
using namespace std;
const int Max = 1000+1; //列表的最大元素个数
const int Radix = 10; //基数
const int KeyNum = 10; //每个元素的最大位数
typedef int KeyType; //排序的元素的类型
typedef struct node
{
KeyType data[KeyNum]; //将待排数的每个位存在数组中
KeyType wholeData; //待排数据整个存储
int next; //指针域
}SLListElem; //静态链表数据元素
typedef struct list
{
SLListElem s[Max]; //0号元素作为头结点,不存数据,指针域仅记录第一个元素的位置
int size;
}SLList; //静态链表
//输入
void input(SLList &L)
{
int num, index;
for(int i=0; i<Max; i++) L.s[i].next = 0; //
index = 0;
while(cin >> num && num != 0)
{
index ++;
for(int i=0; i<KeyNum; i++) L.s[index].data[i] = 0; //
L.s[index].wholeData = num;
//将待排的数据元素分割
for(int i=0; num; i++)
{
L.s[index].data[i] = (num % Radix);
num /= Radix;
}
//前插法建立静态链表
L.s[index].next = L.s[0].next;
L.s[0].next = index;
}
L.size = index;
}
//将数据分割到每个子表中
void distribute(SLList &L, int head[Radix], int tail[Radix], int seq)
{
for(int i=0; i<KeyNum; i++) head[i] = 0;
//!!!!得按静态链表的顺序处理元素!
//遍历静态链表时,很容易习惯上的按照下标来遍历链表
for(int i=L.s[0].next; i; i=L.s[i].next)
{
int pos = L.s[i].data[seq];
if(!head[pos])
{
head[pos] = i;
}
else
{
L.s[tail[pos]].next = i;
}
tail[pos] = i; //尾指针跟上
}
}
//合并各个子表
void collect(SLList &L, int head[Radix], int tail[Radix], int seq)
{
int index, t;
//找到第一个非空子表
for(index=0; index<Radix && !head[index]; index++);
L.s[0].next = head[index];
t = tail[index];
index ++; //指向下一链表
while(index < Radix)
{
//找到下一个非空子表
for(; index < Radix-1 && !head[index]; index++);
if(head[index])
{
L.s[t].next = head[index];
t = tail[index];
}
index ++;
}
L.s[t].next = 0; //静态链表封尾
}
//基数排序
void radixSort(SLList &L)
{
int head[Radix], tail[Radix];
for(int i=0; i<KeyNum; i++)
{
distribute(L, head, tail, i);
collect(L, head, tail, i);
}
}
//输出排序后结果
void output(SLList L)
{
int pointer;
pointer = L.s[0].next;
while(pointer)
{
cout << L.s[pointer].wholeData << ' ';
pointer = L.s[pointer].next;
}
}
int main()
{
SLList L;
input(L);
radixSort(L);
output(L);
system("pause");
return 0;
}
我拿来测试的一组数据:
278 109 63 930 589 184 505 269 8 83 0