快速排序的C++代码实现

基准数的选择:采用范围的中间位置的数

编译环境:C++11

代码实现如下:

#include <type_traits> // std::declval
 
typedef unsigned long size_type;
 
template<typename _Tp>
constexpr size_type distance(const _Tp &_1, const _Tp &_2)
{ return _1 < _2 ? _2 - _1 : _1 - _2; }
 
template<typename _Tp>
void swap(_Tp &a1, _Tp &a2)
{
    _Tp tmp = a1;
    a1 = a2;
    a2 = tmp;
}
 
template<typename _Tp>
struct Comparator
{
    int operator()(const _Tp &arg1, const _Tp &arg2) const
    {
        if(arg1 < arg2) return 1;
        if(arg2 < arg1) return -1;
        return 0;
    }
};


/// 获取范围的基准数
/// 范围:[@beg, @end)  范围,须支持随机迭代
template<typename _RandomIter,
         typename _Compare = Comparator<decltype(*std::declval<_RandomIter>())>>
auto median(_RandomIter beg,
            _RandomIter end,
            _Compare c = _Compare())
    -> decltype(*std::declval<_RandomIter>())
{
    size_type dist = distance(beg, end);
    size_type center = dist / 2;
    _RandomIter left = beg, right = beg + dist - 1;

    if(c(*(left + center), *left) > 0)
    { swap(*(left + center), *left); }

    if(c(*right, *left) > 0)
    { swap(*right, *left); }

    if(c(*right, *(left + center)) > 0)
    { swap(*right, *(left + center)); }

    swap(*(left + center), *(right - 1));
    return *(right - 1);
}

/// 快速排序
/// [@beg, @end)  待排序的范围,同时保存结果,须支持随机迭代
template<typename _RandomIter,
         typename _Compare = Comparator<decltype(*std::declval<_RandomIter>())>>
void qsort(_RandomIter beg,
           _RandomIter end,
           _Compare c = _Compare())
{
    size_type right = distance(beg, end) - 1;
    size_type i = 0, j = right - 1;

    auto pivot(median(beg, end, c));

    while(true)
    {
        while(c(*(beg + (++i)), pivot) > 0);
        while(c(pivot, *(beg + (--j))) > 0);
        if(i < j)
        { swap(*(beg + i), *(beg + j)); }
        else break;
    }
    swap(*(beg + i), *(beg + right - 1));

    qsort(beg, beg + i);
    qsort(beg + i + 1, end);
}

如有问题,欢迎指出!

发布了22 篇原创文章 · 获赞 3 · 访问量 3941

猜你喜欢

转载自blog.csdn.net/qq811299838/article/details/104308544
今日推荐