手写内省排序

本篇记录introsort,不打算过多介绍(自己太菜不会讲),只记录一下代码

// introsort.hpp - Implemment introsort in c++
// Created on 2023/8/31
#include<iterator>
#include<utility>
#include<cmath>
namespace introsort {
    template<typename Iter>
    using iter_value_t = typename std::iterator_traits<Iter>::value_type;

    template<typename Iter>
    using iter_diff_t = typename std::iterator_traits<Iter>::difference_type;

    template<typename RandomAccessIterator, typename Comp>
    inline void insert_sort(RandomAccessIterator beg, RandomAccessIterator end, Comp compare)
    {
        for (RandomAccessIterator i = beg + 1; i < end; ++i)
        {
            iter_value_t<RandomAccessIterator> val = *i;
            RandomAccessIterator j = i;
            for (; j > beg && compare(val, j[-1]); --j) *j = j[-1];
            *j = val;
        }
    }

    template <typename RandomAccessIterator, typename Comp>
    inline void max_heapify(RandomAccessIterator first, RandomAccessIterator target, RandomAccessIterator last, Comp compare)
    {
        typename std::iterator_traits<RandomAccessIterator>::value_type temp = *target;
        --first;
        RandomAccessIterator son;
        for (; (son = target + (target - first)) <= last; target = son)
        {
            if (son < last && compare(*son, *(son + 1)))
                ++son;
            if (compare(temp, *son))
                *target = *son;
            else
                break;
        }
        *target = temp;
    }

    template <typename RandomAccessIterator, typename Comp>
    inline void heap_sort(RandomAccessIterator beg, RandomAccessIterator end, Comp compare)
    {
        if (end - beg > 1)
        {
            for (RandomAccessIterator i = beg + (end - beg) / 2; i >= beg; --i)
                max_heapify(beg, i, end - 1, compare);
            for (; --end > beg; )
            {
                std::swap(*beg, *end);
                max_heapify(beg, beg, end - 1, compare);
            }
        }
    }

    template <typename RandomAccessIterator, typename Comp>
    inline void make_mid_pivot(
        RandomAccessIterator l, RandomAccessIterator mid, RandomAccessIterator r, Comp compare)
    {
        if (compare(*r, *mid))
        {
            if (compare(*mid, *l))
            {
                return;
            }
            std::iter_swap(mid, r);
        }
        if (compare(*mid, *l))
        {
            std::iter_swap(mid, l);
            if (compare(*r, *mid))
                std::iter_swap(mid, r);
        }
    }

    template <typename RandomAccessIterator, typename Comp>
    RandomAccessIterator intro_sort_partition(
        RandomAccessIterator beg, RandomAccessIterator end, Comp compare)
    {
        static int s_rnd = 0x123456;
        RandomAccessIterator l = beg, r = end - 1;
        iter_diff_t<RandomAccessIterator> half = (end - beg) / 2;
        make_mid_pivot(l + s_rnd % half, l + half, r - s_rnd % half, compare);
        ++s_rnd;
        std::iter_swap(r, l + half);
        iter_value_t<RandomAccessIterator> pivot = *r;
        while (1)
        {
            while (l < r && compare(*l, pivot))
                ++l;
            while (l < r && !compare(*r, pivot))
                --r;
            if (l >= r)
                break;
            std::iter_swap(l++, r);
        }
        std::iter_swap(l, end - 1);
        return l;
    }

    template <typename RandomAccessIterator, typename Comp>
    void intro_sort_recursive(
        RandomAccessIterator beg, RandomAccessIterator end, 
        iter_diff_t<RandomAccessIterator> depth, Comp compare)
    {
        if (end - beg <= 16)
        {
            insert_sort(beg, end, compare);
            return;
        }

        if (depth <= 0)
        {
            heap_sort(beg, end, compare);
            return;
        }

        RandomAccessIterator p = intro_sort_partition(beg, end, compare);

        intro_sort_recursive(beg, p, depth - 1, compare);
        for (++p; p < end && !(compare(p[-1], *p) || compare(*p, p[-1])); ) ++p;
        intro_sort_recursive(p, end, depth - 1, compare);
    }

    template <typename RandomAccessIterator, typename Comp>
    void intro_sort(RandomAccessIterator beg, RandomAccessIterator end, Comp compare)
    {
        iter_diff_t<RandomAccessIterator> depth = 
            (iter_diff_t<RandomAccessIterator>)(log(end - beg) * 2.5);
        intro_sort_recursive(beg, end, depth, compare);
    }

    template<typename RandomAccessIterator>
    void intro_sort(RandomAccessIterator beg, RandomAccessIterator end) {
        intro_sort(beg, end, std::less<void>());
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值