基数排序

来源:互联网 发布:c语言简单的冒泡排序 编辑:程序博客网 时间:2024/04/30 20:49

比赛的时候有一道题目,基数排序.输入一串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

原创粉丝点击