1#ifndef NEFORCE_CORE_ALGORITHM_SORT_HPP__
2#define NEFORCE_CORE_ALGORITHM_SORT_HPP__
16NEFORCE_BEGIN_NAMESPACE__
136template <
typename Iterator,
typename Compare>
137bool is_sorted(Iterator first, Iterator last, Compare comp) {
139 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
144 Iterator
next = _NEFORCE
next(first);
145 for (;
next != last; ++first, ++
next) {
146 if (comp(*
next, *first)) {
160template <
typename Iterator>
176template <
typename Iterator,
typename Compare>
179 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
184 Iterator
next = _NEFORCE
next(first);
185 for (;
next != last; ++first, ++
next) {
186 if (comp(*
next, *first)) {
200template <
typename Iterator>
219template <
typename Iterator,
typename Compare>
220NEFORCE_CONSTEXPR20
void bubble_sort(Iterator first, Iterator last, Compare comp) {
221 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
230 for (
auto iter = revstart; iter != revend; ++iter) {
231 bool not_finished =
false;
232 Iterator curend = iter.base();
233 for (Iterator it = first; it != curend; ++it) {
236 if (comp(*
next, *it)) {
253template <
typename Iterator>
254NEFORCE_CONSTEXPR20
void bubble_sort(Iterator first, Iterator last) {
272template <
typename Iterator,
typename Compare>
273NEFORCE_CONSTEXPR20
void cocktail_sort(Iterator first, Iterator last, Compare comp) {
275 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
281 Iterator left = first;
282 Iterator right = last;
286 for (Iterator i = left; i != right; ++i) {
289 if (comp(*
next, *i)) {
299 for (Iterator i = right; i != left; --i) {
302 if (comp(*i, *
prev)) {
317template <
typename Iterator>
336template <
typename Iterator,
typename Compare>
337NEFORCE_CONSTEXPR20
void select_sort(Iterator first, Iterator last, Compare comp) {
339 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
344 for (Iterator i = first; i != last; ++i) {
348 for (; j != last; ++j) {
349 if (comp(*j, *
min)) {
363template <
typename Iterator>
364NEFORCE_CONSTEXPR20
void select_sort(Iterator first, Iterator last) {
382template <
typename Iterator,
typename Compare, enable_if_t<is_ranges_rnd_iter_v<Iterator>,
int> = 0>
383NEFORCE_CONSTEXPR20
void shell_sort(Iterator first, Iterator last, Compare comp) {
385 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
390 auto dist = _NEFORCE
distance(first, last);
391 for (
auto gap = dist / 2; gap > 0; gap /= 2) {
392 for (Iterator i = first + gap; i < last; ++i) {
395 for (j = i; j >= first + gap && comp(temp, *(j - gap)); j -= gap) {
398 *j = _NEFORCE
move(temp);
409template <
typename Iterator>
410NEFORCE_CONSTEXPR20
void shell_sort(Iterator first, Iterator last) {
431template <
typename Iterator,
typename Compare>
432void merge_sort(Iterator first, Iterator last, Compare comp) {
435 const auto n = _NEFORCE
distance(first, last);
439 Iterator mid = first + n / 2;
451template <
typename Iterator>
471template <
typename Iterator,
typename Compare>
472void partial_sort(Iterator first, Iterator middle, Iterator last, Compare comp) {
473 if (first == middle) {
477 for (Iterator i = middle; i < last; ++i) {
478 if (comp(*i, *first)) {
479 inner::pop_heap_aux(first, middle, i, *i, comp);
492template <
typename Iterator>
513template <
typename Iterator1,
typename Iterator2,
typename Compare>
514Iterator2
partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last,
518 if (result_first == result_last) {
521 Iterator2 result_real_last = result_first;
522 while (first != last && result_real_last != result_last) {
523 *result_real_last = *first;
527 _NEFORCE
make_heap(result_first, result_real_last, comp);
528 while (first != last) {
529 if (comp(*first, *result_first)) {
530 _NEFORCE
adjust_heap(result_first, 0, result_real_last - result_first, *first, comp);
534 _NEFORCE
sort_heap(result_first, result_real_last, comp);
535 return result_real_last;
548template <
typename Iterator1,
typename Iterator2>
549Iterator2
partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last) {
567template <
typename Iterator,
typename T,
typename Compare>
568void __insertion_sort_aux(Iterator last, T value, Compare comp) {
569 Iterator
next = last;
571 while (comp(value, *
next)) {
597template <
typename Iterator,
typename Compare>
600 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
605 for (Iterator i = first + 1; i != last; ++i) {
607 if (comp(value, *first)) {
611 inner::__insertion_sort_aux(i, value, comp);
622template <
typename Iterator>
645template <
typename Iterator,
typename Compare>
647 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
649 while (first < last) {
650 if (depth_limit == 0) {
657 if (cut - first < last - cut) {
674template <
typename Iterator>
698template <
typename Iterator,
typename Compare>
699void quick_sort(Iterator first, Iterator last, Compare comp) {
713template <
typename Iterator>
732template <
typename Iterator,
typename Compare>
733void __intro_sort_dispatch(Iterator first, Iterator last,
int depth_limit, Compare comp) {
734 while (last - first > MEMORY_ALIGN_THRESHHOLD) {
735 if (depth_limit == 0) {
743 if (cut - first < last - cut) {
744 inner::__intro_sort_dispatch(first, cut, depth_limit, comp);
747 inner::__intro_sort_dispatch(cut + 1, last, depth_limit, comp);
760NEFORCE_CONST_FUNCTION
constexpr int __log2_int(
int x)
noexcept {
762 for (; x > 1; x >>= 1) {
788template <
typename Iterator,
typename Compare>
789void sort(Iterator first, Iterator last, Compare comp) {
794 inner::__intro_sort_dispatch(first, last, inner::__log2_int(last - first) * 2, comp);
795 constexpr size_t threshhold = MEMORY_ALIGN_THRESHHOLD;
797 if (last - first > threshhold) {
799 for (Iterator i = first + threshhold; i != last; ++i) {
800 inner::__insertion_sort_aux(i, *i, comp);
813template <
typename Iterator>
814void sort(Iterator first, Iterator last) {
815 return _NEFORCE
sort(first, last, _NEFORCE
less<>());
832template <
typename Iterator,
typename Compare>
833NEFORCE_CONSTEXPR20
void tim_sort(Iterator first, Iterator last, Compare comp) {
838 constexpr int min_merge = 32;
839 const auto n = _NEFORCE
distance(first, last);
844 auto step = _NEFORCE
min(
static_cast<decltype(n)
>(min_merge), last - i);
845 Iterator
end = _NEFORCE
next(i, step);
852 for (Iterator left = first; left < last;) {
853 const auto remaining = _NEFORCE
distance(left, last);
854 if (remaining <=
size) {
858 Iterator mid = _NEFORCE
next(left,
size);
859 Iterator right = _NEFORCE
next(left, _NEFORCE
min(2 *
size,
static_cast<int>(remaining)));
875template <
typename Iterator>
876NEFORCE_CONSTEXPR20
void tim_sort(Iterator first, Iterator last) {
893template <
typename Iterator,
typename Compare>
894void nth_element(Iterator first, Iterator nth, Iterator last, Compare comp) {
895 while (last - first > 3) {
913template <
typename Iterator>
922NEFORCE_END_NAMESPACE__
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
constexpr void make_heap(Iterator first, Iterator last, Compare comp)
创建堆
constexpr void adjust_heap(Iterator first, iter_difference_t< Iterator > hole_index, iter_difference_t< Iterator > len, T value, Compare comp)
堆调整辅助函数
constexpr void sort_heap(Iterator first, Iterator last, Compare comp)
将堆转换为有序序列
constexpr bool is_invocable_v
is_invocable的便捷变量模板
constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的前一个位置
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
constexpr Iterator lomuto_partition(Iterator first, Iterator last, Compare comp)
Lomuto 分区算法(基准值归位)
constexpr reverse_iterator< Iterator > make_reverse_iterator(Iterator it) noexcept(is_nothrow_move_constructible_v< Iterator >)
创建反向迭代器
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_backward_aux(first, last, result)))
反向复制范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
bool is_sorted(Iterator first, Iterator last, Compare comp)
检查范围是否已排序
constexpr void select_sort(Iterator first, Iterator last, Compare comp)
选择排序
void introspective_sort(Iterator first, Iterator last, int depth_limit, Compare comp)
内省排序
void sort(Iterator first, Iterator last, Compare comp)
标准排序
Iterator is_sorted_until(Iterator first, Iterator last, Compare comp)
查找首个破坏排序的元素
constexpr void shell_sort(Iterator first, Iterator last, Compare comp)
希尔排序
Iterator2 partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last, Compare comp)
部分排序并复制到另一个范围
void quick_sort(Iterator first, Iterator last, Compare comp)
快速排序
constexpr void bubble_sort(Iterator first, Iterator last, Compare comp)
冒泡排序
constexpr void cocktail_sort(Iterator first, Iterator last, Compare comp)
鸡尾酒排序(双向冒泡排序)
void partial_sort(Iterator first, Iterator middle, Iterator last, Compare comp)
部分排序
void nth_element(Iterator first, Iterator nth, Iterator last, Compare comp)
第n个元素选择
void merge_sort(Iterator first, Iterator last, Compare comp)
归并排序
constexpr void tim_sort(Iterator first, Iterator last, Compare comp)
Tim排序
void insertion_sort(Iterator first, Iterator last, Compare comp)
插入排序
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器