计数排序的C++代码实现

陌路散爱 提交于 2020-02-15 11:11:23

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

编译环境: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); }
}

如有问题,欢迎指出!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!