基数排序是对桶排序的一种改进,这种改进并不提高“桶排序”的性能,但让它适合于更大的元素值集合的情况。
流程
- 选取无序的最弱关键字(数排序的话就是按照进制位从低到高)。
- 从上一次记录的桶中依次取出放入新的桶中。
- 重复过程1和过程2直到全部关键字都被选择过。
演示
输入序列为:23 21 15 34 31
编号 | b[0] | b[1] | b[2] | b[3] | b[4] | b[5] | 操作 |
---|---|---|---|---|---|---|---|
0. | 0 | 0 | 0 | 0 | 0 | 0 | 以个位为关键字排序。输入23,关键字为3。 |
1. | 0 | 0 | 0 | 23 | 0 | 0 | 输入21,关键字为1。 |
2. | 0 | 21 | 0 | 23 | 0 | 0 | 输入15,关键字为5。 |
3. | 0 | 21 | 0 | 23 | 0 | 15 | 输入34,关键字为4。 |
4. | 0 | 21 | 0 | 23 | 34 | 15 | 输入31,关键字为1。 |
5. | 0 | 21 31 | 0 | 23 | 34 | 15 | 以十位为关键字排序。 |
本轮排序结果为:21 31 23 34 15
再对该序列以十进制数字为关键字排序。
编号 | b[0] | b[1] | b[2] | b[3] | b[4] | b[5] | 操作 |
---|---|---|---|---|---|---|---|
6. | 0 | 0 | 0 | 0 | 0 | 0 | 以十位为关键字排序。输入21,关键字为2。 |
7. | 0 | 0 | 21 | 0 | 0 | 0 | 输入31,关键字为3。 |
8. | 0 | 0 | 21 | 31 | 0 | 0 | 输入23,关键字为2。 |
10. | 0 | 0 | 21 23 | 31 | 0 | 0 | 输入34,关键字为3。 |
11. | 0 | 0 | 21 23 | 31 34 | 0 | 0 | 输入15,关键字为1。 |
12. | 0 | 15 | 21 23 | 31 34 | 0 | 0 | 输出。 |
结果:15 21 23 31 34
代码
#include <stdio.h>
#include <math.h>
#include <string.h>
#define N 1000001
int n,a[N],maxx,len,b[10],t[10],nxt[N],y[N],tot;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i)
if (scanf("%d",&a[i]),a[i]>maxx) maxx=a[i];
len=log10(maxx)+1;
for (int ovo=1;ovo<=len;tot=0,++ovo)
{
memset(b,0,sizeof(b));
memset(t,0,sizeof(t));
memset(nxt,0,sizeof(nxt));
for (int i=1;i<=n;++i)
{
int x=a[i];
for (int j=1;j<ovo;++j) x/=10;
x%=10;
if (b[x]==0) y[++tot]=a[i],b[x]=t[x]=tot;
else
{
y[++tot]=a[i];
nxt[t[x]]=tot;
t[x]=tot;
}
}
for (int i=0,k=0;i<=9;++i)
for (int j=b[i];j;j=nxt[j])
a[++k]=y[j];
}
for (int i=1;i<=n;++i) printf("%d ",a[i]);
}
时间复杂度
关键字很少的时候可以达到O(n)的级别。
如果只有一个关键字成为狭义桶排。