【C++算法】计数排序

计数排序,并非基数排序。暂时只支持数值型

编译环境:C++11

代码实现如下:

#include <cstring> // std::memset
#include <type_traits> // std::declval

/* 计数排序
 * [@beg, @end)  待排序的范围,同时保存结果,须支持前向迭代
 * [@min, @max)  待排序范围的最小值和最大值,不包含最大值
 */
template<typename _ForwardIter>
void csort(_ForwardIter beg,
           _ForwardIter end,
           typename std::remove_reference<decltype(*std::declval<_ForwardIter>())>::type min,
           typename std::remove_reference<decltype(*std::declval<_ForwardIter>())>::type max)
{
    using __element_type = typename std::remove_reference<decltype(*std::declval<_ForwardIter>())>::type;
    static_assert(std::is_arithmetic<__element_type>::value, "only support arithmetic type temporary");

    __element_type interval = min;
    max -= min;
    min = 0;
    __element_type *ele = new __element_type[static_cast<std::size_t>(max)];
    std::memset(ele, 0, static_cast<size_type>(max) * sizeof(__element_type));

    _ForwardIter it = beg;
    while(it != end)
    { ele[(*it++) - interval]++; }
    
    __element_type *visit = ele;
    for(long long i = 0; i < max; ++i, ++visit)
    {
        while((*visit)-- > 0)
        { *beg++ = i + interval; }
    }
    delete[] ele;
}

/* 计数排序
 * [@beg, @end)  待排序的范围,同时保存结果,须支持前向迭代
 */
template<typename _ForwardIter>
void csort(_ForwardIter beg,
           _ForwardIter end)
{
    using __element_type = typename std::remove_reference<decltype(*std::declval<_ForwardIter>())>::type;
    static_assert(std::is_arithmetic<__element_type>::value, "only support arithmetic type temporary");
    __element_type max = *beg, min = *beg;
    _ForwardIter it = beg;
    for(++it; it != end; ++it)
    {
        if(*it > max)
        { max = *it; }
        else if(*it < min)
        { min = *it; }
    }
    if(max != min)
    { csort(beg, end, min, max); }
}

如有问题,欢迎指出!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值