冒泡排序及其优化的C++代码实现

谁说胖子不能爱 提交于 2020-02-14 11:35:46

关于冒泡排序算法,这里就不多说了。

简单说一下优化,一般的冒泡排序是单向的,而其优化之一就是双向冒泡:正向扫描获取最大值,反向扫描获取最小值。

由于C++11以前的实现有点复杂,在此就基于C++11新特性来实现,并写成库的形式。

编译环境:C++11

代码实现如下:

#include <type_traits> // std::declval

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;
    }
};

typedef unsigned long size_type;

/// 普通冒泡排序
/// 范围:[beg, end)
/// 参数限定:支持前向迭代
template<typename _ForwardIter,
         typename _Compare = Comparator<decltype(*std::declval<_ForwardIter>())>>
void fsort(_ForwardIter beg,
           _ForwardIter end,
           _Compare c = _Compare())
{
    _ForwardIter last_pos = end;
    for(_ForwardIter v = beg; v != end; ++v)
    {
        _ForwardIter current_pos = end;
        _ForwardIter b = beg, temp = b;
        for(++temp; temp != last_pos; ++b, ++temp)
        {
            if(c(*temp, *b) > 0)
            {
                swap(*temp, *b);
                current_pos = temp;
            }
        }
        last_pos = current_pos;
        if(last_pos == end)
        { return; }
    }
}

/// 双向冒泡排序
/// 范围:[beg, end)
/// 参数限定:支持前向迭代和后向迭代
template<typename _BothIter,
         typename _Compare = Comparator<decltype(*std::declval<_BothIter>())>>
void bsort(_BothIter beg,
           _BothIter end,
           _Compare c = _Compare())
{
    _BothIter max_pos = end;
    _BothIter min_pos = beg;
    for(_BothIter v = beg; v != end; ++v)
    {
        _BothIter current_pos = end;
        _BothIter b = min_pos, temp = b;
        for(++temp; temp != max_pos; ++b, ++temp)
        {
            if(c(*temp, *b) > 0)
            {
                swap(*temp, *b);
                current_pos = temp;
            }
        }
        if(current_pos == end)
        { return; }
        max_pos = current_pos;
        current_pos = end;
        b = max_pos;
        temp = b;
        for(--temp; b != min_pos; --b, --temp)
        {
            if(c(*b, *temp) > 0)
            {
                swap(*temp, *b);
                current_pos = b;
            }
        }
        ++min_pos;
        if(current_pos == end)
        { return; }
    }
}

如有问题,欢迎指出!

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