基数排序

一. 算法描述

基数排序(以整形为例),将整形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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值