计数排序

在所有基于比较的排序算法中,最快的算法其时间复杂度为O(NlogN),事实上可以证明,这已经是基于比较的排序算法的时间复杂度下界了。但有一种实现简单的非比较排序算法可以突破基于比较的排序算法这一时间下界——计数排序(Counting Sort)。

如果我们的待排序序列为整数且有一个已知的数值范围K,那么计数排序可以在O(N+K)的时间复杂度内将序列排序好。在多数情况下计数排序的效率比任何基于比较的排序算法都要高,除非O(K)>O(NlogN)。计数排序是一种以空间换时间的算法。

计数排序的基本思想是对每一个数,统计其他小于这个数的个数,如此一来就可以确定这个数在排序后所在的位置。对于存在重复元素的情况,我们需要先对每一个重复元素进行统计。

const int k = 100; //元素范围

void CountingSort(vector<int> &vec)
{
    vector<int> count(k, 0);

    //统计重复元素
    for (const int &i : vec)
    {
        ++count.at(i);
    }

    //统计比i小的元素的个数以确定排序后i所在的位置
    for (size_t i = 1; i < vec.size(); ++i)
    {
        count.at(i) += count.at(i-1);
    }

    //将元素一个个放入对应位置
    vector<int> aux = vec;
    for (size_t i = 0; i < vec.size(); ++i)
    {
        vec[--count[aux[i]]] = aux[i];
        //vec.at(--count.at(aux.at(i))) = aux.at(i);
    }
}

一般情况下计数排序的效率都非常高,但其仅局限于整数排序且已知元素值范围的情况,比如对一个数据量非常大但其元素范围相对很小的应用场景——如上千万考生按成绩排序(假设成绩都为整数且范围是[0, 100])。 此外,计数排序的核心思想也是基数排序的重要组成部分。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值