码迷,mamicode.com
首页 > 编程语言 > 详细

浅谈计数排序

时间:2018-09-14 23:05:44      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:const   inline   更新   mes   cst   利用   std   using   数据   

所谓计数排序,就是建立在计数上的排序。

计数排序不以比较为基础,所以可以打破比较排序\(O(nlogn)\)的复杂度下界。

我们只要计算出比\(i\)小的数字有多少个,就可以知道\(i\)在数据里的排名。然后根据排名,我们就可以反造一波排好序的数据了。

我们用\(rk[i]\)记录第\(i\)个数据的排名,\(sum[i]\)记录权值1~\(i\)一共有多少个数据。然后\(a[i]\)的排名就是\(sum[i]\),如果有相同的权值那么每次用\(sum[i]\)更新一个数据的\(rk\)后都要把\(sum[i]\)--。

那么根据\(ans[rk[i]]=a[i]\),一个一个把数据往\(ans\)数组里填就是了。

时间复杂度:\(O(n+maxv)\)

空间复杂度:\(O(n+maxv)\)

代码如下:

#include <cstdio>
using namespace std;

const int maxn=1e6+5;

int n,rk[maxn];
int a[maxn],b[maxn],sum[maxn];

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<‘0‘||ch>‘9‘;ch=getchar())if(ch==‘-‘)f=-1;
    for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar())x=x*10+ch-‘0‘;
    return x*f;
}

int main() {
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read(),sum[a[i]]++;
    for(int i=1;i<=n;i++)
        sum[i]=sum[i]+sum[i-1];//利用前缀和求sum
    for(int i=1;i<=n;i++)
        rk[i]=sum[a[i]]--;//求rk[i]
    for(int i=1;i<=n;i++)
        b[rk[i]]=a[i];//求rk的反数组
    for(int i=1;i<=n;i++)
        printf("%d ",b[i]);//rk的反数组就是排好序的数据
    return 0;
}

浅谈计数排序

标签:const   inline   更新   mes   cst   利用   std   using   数据   

原文地址:https://www.cnblogs.com/AKMer/p/9649032.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!