标题：基数排序
解法
基数排序的方式可以采用LSD（Least significant digital）或MSD（Most significant digital），LSD的排序方式由键值的最右边开始，而MSD则相反，由键值的最左边开始。 
以LSD为例，假设原来有一串数值如下所示： 
73, 22, 93, 43, 55, 14, 28, 65, 39, 81 
首先根据个位数的数值，在走访数值时将它们分配至编号0到9的桶子中： 
0 
1 81 
2 22 
3 73 93 43 
4 14 
5 55 65 
6 
7 
8 28 
9 39 
接下来将这些桶子中的数值重新串接起来，成为以下的数列： 
81, 22, 73, 93, 43, 14, 55, 65, 28, 39 
接着再进行一次分配，这次是根据十位数来分配： 
0 
1 14 
2 22 28 
3 39 
4 43 
5 55 
6 65 
7 73 
8 81 
9 93 
接下来将这些桶子中的数值重新串接起来，成为以下的数列： 
14, 22, 28, 39, 43, 55, 65, 73, 81, 93 
这时候整个数列已经排序完毕；如果排序的对象有三位数以上，则持续进行以上的动作直至最高位数为止。 
LSD的基数排序适用于位数小的数列，如果位数多的话，使用MSD的效率会比较好。MSD的方式与LSD相反，是由高位数为基底开始进行分配，但在分配之后并不马上合并回一个数组中，而是在每个“桶子”中建立“子桶”，将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。
效率分析
时间效率：设待排序列为n个记录，d个关键码，关键码的取值范围为radix，则进行链式基数排序的时间复杂度为O(d(n+radix))，其中，一趟分配时间复杂度为O(n)，一趟收集时间复杂度为O(radix)，共进行d趟分配和收集。 空间效率：需要2*radix个指向队列的辅助空间，以及用于静态链表的n个指针。
实现的方法
最高位优先(Most Significant Digit first)法，简称MSD法：先按k1排序分组，同一组中记录，关键码k1相等，再对各组按k2排序分成子组，之后，对后面的关键码继续这样的排序分组，直到按最次位关键码kd对各子组排序后。再将各组连接起来，便得到一个有序序列。
最低位优先(Least Significant Digit first)法，简称LSD法：先从kd开始排序，再对kd-1进行排序，依次重复，直到对k1排序后便得到一个有序序列。
实现原理
基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的：将所有待比较数值（正整数）统一为同样的数位长度，数位较短的数前面补零。然后，从最低位开始，依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
基数排序的方式可以采用LSD（Least significant digital）或MSD（Most significant digital），LSD的排序方式由键值的最右边开始，而MSD则相反，由键值的最左边开始。
实现
* C#include <stdio.h>
#include <stdlib.h>
int main(){
int data[10]={73,22,93,43,55,14,28,65,39,81};
int temp[10][10]={0};  基数排序算法int order[10]={0};
int i,j,k,n,lsd;
k=0;n=1;
printf("\n排序前: ");
for (i=0;i<10;i++) printf("%d ",data[i]);
putchar('\n');
while (n<=10){
for (i=0;i<10;i++){
lsd=((data[i]/n)%10);
temp[lsd][order[lsd]]=data[i];
order[lsd]++;
}
printf("\n重新排列: ");
for (i=0;i<10;i++){
if(order[i]!=0)
for (j=0;j<order[i];j++){
data[k]=temp[i][j];
printf("%d ",data[k]);
k++;
}
order[i]=0;
}
n*=10;
k=0;
}
putchar('\n');
printf("\n排序后: ");
for (i=0;i<10;i++) printf("%d ",data[i]);
return 0;
}
* Javapublic class RadixSort { 
public static void sort(int[] number, int d) { 
int k=0;
int n=1;
int m=1;//控制键值排序依据在哪一位
int[][] temp = new int[number.length][number.length]; 
int[] order = new int[number.length]; 
while(m <= d) { 
for(int i = 0; i < number.length; i++) { 
int lsd = ((number[i] / n) % 10); 
temp[lsd][order[lsd]] = number[i]; 
order[lsd]++; 
} 
for(int i = 0; i < d; i++) { 
if(order[i] != 0) 
for(int j = 0; j < order[i]; j++) { 
number[k] = temp[i][j]; 
k++; 
} 
order[i] = 0; 
} 
n *= 10; 
k = 0; 
m++;
} 
} 
public static void main(String[] args) { 
int[] data = 
{73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100}; 
RadixSort.sort(data, 10); 
for(int i = 0; i < data.length; i++) { 
System.out.print(data[i] + " "); 
} 
}
* pascaltype link=^node;
node=record
data:integer;
next:link;
end;
var i,j,l,m,k,n:integer;
a:array[1..100] of integer;
s:string;
q,head:array[0..9] of link;
p,p1:link;
begin
readln(n);
writeln('Enter data:');
for i:=1 to n do read(a[i]);
for i:=5 downto 1 do
begin
for j:=0 to 9 do
begin
new(head[j]);
head[j]^.next:=nil;
q[j]:=head[j]
end;
for j:=1 to n do
begin
str(a[j],s);
for k:=1 to 5-length(s) do
s:='0'+ s;
m:=ord(s[i])-48;
new(p);
p^.data:=a[j];
p^.next:=nil;
q[m]^.next:=p;
q[m]:=p;
end;
l:=0;
for j:=0 to 9 do
begin
p:=head[j];
while p^.next<>nil do
begin
l:=l+1;p1:=p;p:=p^.next;dispose(p1);a[l]:=p^.data;
end;
end;
end;
writeln('Sorted data:');
for i:= 1 to n do
write(a[i]:6);
end.
c++实现基数排序
int maxbit(int data[],int n) //辅助函数，求数据的最大位数
{
int d = 1; //保存最大的位数
int p =10;
for(int i = 0;i < n; ++i)
{ 
while(data[i] >= p)
{
p *= 10;
++d;
}
}
return d;
}　
void radixsort(int data[],int n) //基数排序
{
int d = maxbit(data,n);
int * tmp = new int[n];
int * count = new int[10]; //计数器
int i,j,k;
int radix = 1;
for(i = 1; i<= d;i++) //进行d次排序
{
for(j = 0;j < 10;j++)
count[j] = 0; //每次分配前清空计数器
for(j = 0;j < n; j++)
{
k = (data[j]/radix)%10; //统计每个桶中的记录数
count[k]++;
}
for(j = 1;j < 10;j++)
count[j] = count[j-1] + count[j]; //将tmp中的位置依次分配给每个桶
for(j = n-1;j >= 0;j--) //将所有桶中记录依次收集到tmp中
{
k = (data[j]/radix)%10;
t
AAuto语言实现基数排序
io.open();//打开控制台
/*
*-------------------------------------------------------
* 基数排序
**------------------------------------------------------
*/
/*
基数排序从低位到高位进行，使得最后一次计数排序完成后，数组有序。
其原理在于对于待排序的数据，整体权重未知的情况下，
先按权重小的因子排序，然后按权重大的因子排序。
例如比较时间，先按日排序，再按月排序，最后按年排序，仅需排序三次。
但是如果先排序高位就没这么简单了。
基数排序源于老式穿孔机，排序器每次只能看到一个列，
很多教科书上的基数排序都是对数值排序，数值的大小是已知的，与老式穿孔机不同。
将数值按位拆分再排序，是无聊并自找麻烦的事。
算法的目的是找到最佳解决问题的方案，而不是把简单的事搞的更复杂。
基数排序更适合用于对时间、字符串等这些整体权值未知的数据进行排序。
这时候基数排序的思想才能体现出来，例如字符串，如果从高位（第一位）往后排就很麻烦。
而反过来，先对影响力较小，排序排重因子较小的低位（最后一位）进行排序就非常简单了。
这时候基数排序的思想就能体现出来。
又或者所有的数值都是以字符串形式存储，就象穿孔机一样，每次只能对一列进行排序。
这时候基数排序也适用，例如：对{"193";"229";"233";"215"}进行排序
下面我们使用基数排序对字符串进行排序。
对每个位循环调用计数排序。
*/
//计数排序算法
radix_sort = function( array ,maxlen){
//AAuto在字符串索引越界时，会返回0，这使基数排序的实现更加简单。
//我们首先找出最大的排序长度，然后对于不足此长度的字符串，尾部都假定以0补齐。
//对于超出此长度的位在比较时忽略
if(!maxlen){ 
maxlen =0;
for(i=1;#array;1){
maxlen = math.max(maxlen,#array[i] )
}
}
//else{
//最大排序长度也可以从参数中传过来，这样就不用遍历所有字符串了
//}
//从字符串的最后一位开始，到第一位
for(pos=maxlen;1;-1){
//按当前位的字节码计数排序
var array_sorted ={};
var count = {};
for(i=0;256 ){
count[i] = 0;
}
var bytecode;
for(i=1;#array;1){
//如果pos大于字符串长度，AAuto会返回0，这使基数排序的实现更容易
bytecode = array[i][pos] ;
count[ bytecode ] ++; //count[n] 包含等于n的个数 
}
//统计位置
for(i=1;256;1){
count[i] += count[i-1]; //count[i] 包含小于等于i的个数 
}
var n;
for(i=#array;1;-1){
n = array[i][pos] 
array_sorted[ count[n] ] = array[i];
count[n]--;//防止相同的元素n再次出现，将计数减一 
}
array = array_sorted; 
} 
return array
}
io.print("----------------")
io.print("基数排序( 线性时间排序 )")
io.print("----------------")
array ={"AAuto is quicker and better,just try it!";"AAuto Quicker";"193";"229";"233";"215";"Hello Word";"abc";"abcd";"xd";"adcd";"eddd";"ah";"ai";"aj";"ajkk"}; 
//排序
array = radix_sort(array )
//输出结果
for(i=1;#array;1){
io.print( array[i] )
}
execute("pause") //按任意键继续
io.close();//关闭控制台