第一次接触基数排序是在学习后缀数组(有感兴趣的可以看一下-->后缀数组)的时候,感觉和桶排序很像,时间复杂度能达到,是一种很高效的排序方法,下面就来看看基数排序是怎么进行排序的吧!
注:本文主要讲述从小到大排序,从大到小排序与之类似,如果你真的理解了基数排序,不难实现从大到小排序
排序方法:
给定一个需要进行排序的数组a和十个桶(编号从0到9),对于数组a中每个元素,先根据其个位数字将这个元素放到对应的桶中(即如果这个元素个位数字是a(a肯定满足:),就将这个元素放到编号为a的桶里),将所有元素都放到对应的桶里后,再将0到9的桶里的元素依次拿出来放回a数组里,然后再根据十位数、百位数……重复这个操作,最终a数组就是排好序的了
举例说明:
给定数组:100、181、77、10、5、98、102、11、63
根据个位数进行排序:
桶0 | 100、10 |
桶1 | 181、11 |
桶2 | 102 |
桶3 | 63 |
桶4 | |
桶5 | 5 |
桶6 | |
桶7 | 77 |
桶8 | 98 |
桶9 |
排序后:100、10、181、11、102、63、5、77、98
根据十位数进行排序:
桶0 | 100、102、5 |
桶1 | 10、11 |
桶2 | |
桶3 | |
桶4 | |
桶5 | |
桶6 | 63 |
桶7 | 77 |
桶8 | 181 |
桶9 | 98 |
排序后:100、102、5、10、11、63、77、181、98
根据百位数进行排序:
桶0 | 5、10、11、63、77、98 |
桶1 | 100、102、181 |
桶2 | |
桶3 | |
桶4 | |
桶5 | |
桶6 | |
桶7 | |
桶8 | |
桶9 |
排序后:5、10、11、63、77、98、100、102、181
此时排序结束,是不是很神奇,不知不觉就变成有序的了
代码实现:
注:尽管你可能已经知道了排序过程,但实现排序过程也是一个难题,你最好能理解下面代码,如果有不太明白的地方可以留言(主要是我不想写注释了)
#include <bits/stdc++.h>
using namespace std;
#define infy 0x3f3f3f3f
#define lowbit(x) (x&(-x))
#define e exp(1)
#define pi acos(-1)
typedef long long int ll;
const int maxn=1009;
int n,a[maxn];
int b[10];
void radix_sort(int a[],int se)
{
int ma=-1,fg=1;
int tp[maxn];
for(int i=1;i<=se;i++)
ma=max(ma,a[i]);
while(ma)
{
for(int i=0;i<=9;i++)
b[i]=0;
for(int i=1;i<=se;i++)
b[(a[i]/fg)%10]++;
for(int i=1;i<=9;i++)
b[i]+=b[i-1];
for(int i=se;i>=1;i--)
tp[b[(a[i]/fg)%10]--]=a[i];
for(int i=1;i<=se;i++)
a[i]=tp[i];
ma/=10;
fg*=10;
}
}
int main()
{
cin.sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
radix_sort(a,n);
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}