基数排序

比赛的时候有一道题目,基数排序.输入一串1000000个以内的数据,从小到大排序.我说:这不是很简单的么?

#include<bits/stdc++.h>
using namespace std;
int a[1000010],n;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for (int i=1;i<=n;i++) printf("%d ",a[i]);
}

用sort就这么水过去了.可是基数排序那么精彩的排序不学,以后怎么见人?基数排序是以一个进制为基准,将所有数字按照这个进制表示,先以末位作为排序基准,放到一个桶里,然后把桶里的东西拿出来重新排好.然后又以从末位数过来第二位排序,排好.以此类推,当排到最大位之后排序就结束了.具体看看代码吧.这个代码以10进制为基准.我原来编的时候复杂度是nlogn,因为我犯傻用了堆.

#include<bits/stdc++.h>
using namespace std;
const int boss=1e6;
int a[boss+10],tmp[boss+10],n;
int maxbit(int n)//计算最大的位数
{
int d=1,s=0;
for (int i=1;i<=n;i++) while (a[i]>d) d*=10,s++;
return s;
}
void radixsort()
{
int i,j,k,d=maxbit(n),radix=1,counts[10];//counts是一个桶,存放该位为0-9的个数
for (i=1;i<=d;i++,radix*=10)//每次以radix作为基数
  {
  for (j=0;j<10;j++) counts[j]=0;//清空桶
  for (j=1;j<=n;j++) counts[a[j]/radix%10]++;//看看这一位是多少,放到桶里去
  for (j=1;j<10;j++) counts[j]+=counts[j-1];//神操作,看清楚,求前缀和,也就是这个数在所有数中以这一位排序排多少名(当然有很多并列)
  for (j=n;j>=1;j--)//在每一位当中排序之后结果是从大到小的,所以要倒过来扫
    {
    k=a[j]/radix%10;//看看它这一位是多少
    tmp[counts[k]]=a[j];//按照这一位放到临时储存的数组里去
    counts[k]--;
    }
  for (j=1;j<=n;j++) a[j]=tmp[j];
  }
}
int main()
{
for (int i;scanf("%d",&n)!=EOF;printf("\n"))
  {
  for (i=1;i<=n;i++) scanf("%d",&a[i]);
  radixsort();
  for (i=1;i<=n;i++) printf("%d ",a[i]);    
  }
}

如此精彩.在代码中把10替换成别的数就可以以别的数作为基准排序了.以不同的数作为基准效率是不一样的.
http://tttnns-blog.readthedocs.io/blogs/11-50.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值