基数排序

参考链接:https://blog.csdn.net/daiyudong2020/article/details/52566364

https://blog.csdn.net/double_happiness/article/details/72452243

思路:比较位是“个位,十位,百位·······”根据相同的比较位把数据放到同一个桶中。

时间复杂度是 d*n(d 是数据中最大的那个数所拥有的位数)  当n特别大,d特别小的时候,排序速度可比堆排序和快速排序的速度还要快!比如十万个都是小于10的数字用基数排序比堆排还要快 。或者高考成绩排序。。。。因为d = 3(最高分也就3位数字),n特别大, 此时d*n比n* logn还要小

 


#include<iostream>
using namespace std;
#define maxn 100005
int a[maxn],temp[maxn];
//获取数组中最大的那个数的位数
int  GetMaxDigit(int a[], int n)
{
	int base = 10;
	
	int num = 1;
	for(int i=0;i<n;i++)
	{
		while(a[i] >= base)
		{
			num++;
			base*=10;
		}
	}
	return num;
}
//基数排序
void Bucket_Sort(int a[], int size)
{
	int count[10];
	int d= GetMaxDigit(a, size);
	int base = 1;
	for(int i = 0;i < d; i++)//最大位数是控制循环次数(即通过多少此排序才可以是整个数组有序)
	{
		for(int i =0 ;i < 10;i++)//清空桶,即统计各个数字出现的次数
			count[i] = 0;
		for(int i = 0;i < size; i++)
		{
			int k = (a[i]/base)%10;
			count[k]++;//统计“比较位”上的数字出现的次数
			//比较位即是个位,十位,百位........以此类推
		}
		for(int i=1;i < 10;i++)
			count[i] += count[i-1];/*确定“比较位是(i=1,2,3,4,5,6,7,8,9,0)”的数字
								  中最后一个存放在temp数组的第几个位置,即比较位为k的时候
								   能放在数组temp 的第count[i]个位置,注意不是下标
								*/

		for(int j=size-1; j>=0;j--)/*从后往前扫才能把数字放到正确的位置*
								   因为count数组存放的是最右边的位置*/
		{
			int k = (a[j]/base)%10;//求得比较位
			temp[count[k] - 1] = a[j];/*根据比较位将数字a[j]放到temp数组第count[k]个位置上
									  即temp数组中下标为(count[k] - 1 )的位置上*/
			count[k]--;//对应比较位为k的数据能够放在temp数组最右边位置减少1

		}

		for(int i=0;i<size;i++)
			a[i] = temp[i];//把数组复制会原来的数组 
		base *= 10;
	}

}
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	//int t = GetMaxDigit(a, n);
	//cout<<t<<endl;
	Bucket_Sort(a, n);
	for(int i = 0;i < n;i++)
		cout<<a[i]<<" ";
	cout<<endl;
	system("pause");
}



     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值