一. 算法描述
基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
以【521 310 72 373 15 546 385 856 187 147】序列为例,具体细节如下图所示
前半部分转自:http://blog.csdn.net/cjf_iceking/article/details/7943609
基数排序是按元素有效位数值进行分配和收集的排序方法 基数排序排序的基本思想以排序十进制数为例:设立10个队列分别编号0到9。首先按最低有有效位(个位数)值,把n个元素分配到10个队列中。然后按队列编号从小到大将各队列中的元素收集起来。接着将收集起来的元素按次低有效位的值分配到10个队列中去。重复上述的分配和收集过程。直到分配到元素最高有效位 最后一次收集的元素将是一个有序序列
基数排序的程序实现。可以先求出待排序元素的最大值maxValue,然后求出最大值的位数maxBit 一共需要进行maxBit 次的分配和收集操作。
桶可以用队列去描述这样比较简单和直观
则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集
下面是参考程序:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
/********************************************************
*函数名称:GetNumInPos
*参数说明:num 一个整形数据
* pos 表示要获得的整形的第pos位数据
*说明: 找到num的从低到高的第pos位的数据
*********************************************************/
int GetNumInPos(int num,int pos) //找到num的从低到高的第pos位的数据 即可以得到装入的桶号
{
int temp = 1;
for (int i = 0; i < pos - 1; i++)
temp *= 10;
return (num / temp) % 10;
}
int NumberOfBit(int number)//判读一个十进制整形数是多少位 如23为2位 则返回2
{
int count=0;
while(number)
{
count++;
number=number/10;
}
return count;
}
void RadixSort(int *a,int length)
{
if(a==NULL||length<=0)
{
return ;
}
int maxValue=a[0];//
for(int i=1;i<length;i++)//找待排序数组中元素的最大值
{
if(maxValue<a[i])
{
maxValue=a[i];
}
}
int maxBit=NumberOfBit(maxValue);
queue<int> Queue[10];//用Queue[0]....Queue[9] 九个队列来表示桶
int pos=1;//pos范围为1到maxBit 表示从第一位开始 一直到待排序数组中元素的最高位
while(maxBit--)//当待排序数组中元素的最大值的位数为maxBit 时,需要进行maxBit次的分配和收集操作
{
for(int i=0;i<length;i++)
{
int index=GetNumInPos(a[i],pos); //根据元素第pos位数值将元素分配到相应的桶号中 即分配操作
Queue[index].push(a[i]);
}
int j=0;//数组下标索引
for(int i=0;i<length;i++)//改变此处for(int i=9;i>=0;i--)变为从大大小排列
{
while(!Queue[i].empty())
{
a[j++]=Queue[i].front();//根据桶号顺序的收集数组元素 收集操作
Queue[i].pop();
}
}
pos++;//开始 分配下一位
}
}
int main()
{
int a[]={1,2,3,43,545,323,3,5,77666,};
int length=sizeof(a)/sizeof(a[0]);
RadixSort(a,length);
for(int i=0;i<length;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}