本篇记录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>());
}
}
841

被折叠的 条评论
为什么被折叠?



