zoukankan      html  css  js  c++  java
  • 浅谈计数排序

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

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

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

    我们用(rk[i])记录第(i)个数据的排名,(sum[i])记录权值1~(i)一共有多少个数据。然后(a[i])的排名就是(sum[a[i]]),如果有相同的权值那么每次用(sum[a[i]])更新一个数据的(rk)后都要把(sum[a[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;
    }
    
  • 相关阅读:
    3月工作问题总结
    【读书笔记】linux编程艺术
    项目管理工具 Trac入门
    [node.js]开放平台接口调用测试
    mysql 高并发更新计数问题
    memcache 问题 socket or its streams already null in trueClose call
    hadoop学习笔记
    node.js学习与应用
    mc参数备忘&javajson备忘
    WCF技术剖析_学习笔记之三
  • 原文地址:https://www.cnblogs.com/AKMer/p/9649032.html
Copyright © 2011-2022 走看看