1#ifndef NEFORCE_CORE_ALGORITHM_SORT_HPP__
2#define NEFORCE_CORE_ALGORITHM_SORT_HPP__
16NEFORCE_BEGIN_NAMESPACE__
155template <
typename Iterator,
typename Compare>
156bool is_sorted(Iterator first, Iterator last, Compare comp) {
158 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
163 Iterator
next = _NEFORCE
next(first);
164 for (;
next != last; ++first, ++
next) {
165 if (comp(*
next, *first)) {
179template <
typename Iterator>
195template <
typename Iterator,
typename Compare>
198 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
203 Iterator
next = _NEFORCE
next(first);
204 for (;
next != last; ++first, ++
next) {
205 if (comp(*
next, *first)) {
219template <
typename Iterator>
242template <
typename Iterator,
typename Compare>
243void merge_sort(Iterator first, Iterator last, Compare comp) {
246 const auto n = _NEFORCE
distance(first, last);
250 Iterator mid = first + n / 2;
262template <
typename Iterator>
282template <
typename Iterator,
typename Compare>
283void partial_sort(Iterator first, Iterator middle, Iterator last, Compare comp) {
284 if (first == middle) {
288 for (Iterator i = middle; i < last; ++i) {
289 if (comp(*i, *first)) {
290 inner::pop_heap_aux(first, middle, i, *i, comp);
303template <
typename Iterator>
324template <
typename Iterator1,
typename Iterator2,
typename Compare>
325Iterator2
partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last,
329 if (result_first == result_last) {
332 Iterator2 result_real_last = result_first;
333 while (first != last && result_real_last != result_last) {
334 *result_real_last = *first;
338 _NEFORCE
make_heap(result_first, result_real_last, comp);
339 while (first != last) {
340 if (comp(*first, *result_first)) {
341 _NEFORCE
adjust_heap(result_first, 0, result_real_last - result_first, *first, comp);
345 _NEFORCE
sort_heap(result_first, result_real_last, comp);
346 return result_real_last;
359template <
typename Iterator1,
typename Iterator2>
360Iterator2
partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last) {
378template <
typename Iterator,
typename T,
typename Compare>
379void __insertion_sort_aux(Iterator last, T value, Compare comp) {
380 Iterator
next = last;
382 while (comp(value, *
next)) {
408template <
typename Iterator,
typename Compare>
411 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
416 for (Iterator i = first + 1; i != last; ++i) {
418 if (comp(value, *first)) {
422 inner::__insertion_sort_aux(i, value, comp);
433template <
typename Iterator>
456template <
typename Iterator,
typename Compare>
458 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
460 while (first < last) {
461 if (depth_limit == 0) {
467 first, last, _NEFORCE
median(*first, *(first + (last - first) / 2), *(last - 1), comp), comp);
480template <
typename Iterator>
504template <
typename Iterator,
typename Compare>
505void quick_sort(Iterator first, Iterator last, Compare comp) {
507 Iterator pov = last - 1;
521template <
typename Iterator>
540template <
typename Iterator,
typename Compare>
541void __intro_sort_dispatch(Iterator first, Iterator last,
int depth_limit, Compare comp) {
542 while (last - first > MEMORY_ALIGN_THRESHHOLD) {
543 if (depth_limit == 0) {
549 first, last, _NEFORCE
median(*first, *(first + (last - first) / 2), *(last - 1), comp), comp);
550 inner::__intro_sort_dispatch(cut, last, depth_limit, comp);
562NEFORCE_CONST_FUNCTION
constexpr int __log2_int(
int x)
noexcept {
564 for (; x > 1; x >>= 1) {
590template <
typename Iterator,
typename Compare>
591void sort(Iterator first, Iterator last, Compare comp) {
596 inner::__intro_sort_dispatch(first, last, inner::__log2_int(last - first) * 2, comp);
597 constexpr size_t threshhold = MEMORY_ALIGN_THRESHHOLD;
599 if (last - first > threshhold) {
601 for (Iterator i = first + threshhold; i != last; ++i) {
602 inner::__insertion_sort_aux(i, *i, comp);
615template <
typename Iterator>
616void sort(Iterator first, Iterator last) {
633template <
typename Iterator,
typename Compare>
634void nth_element(Iterator first, Iterator nth, Iterator last, Compare comp) {
635 while (last - first > 3) {
637 first, last, _NEFORCE
median(*first, *(first + (last - first) / 2), *(last - 1), comp), comp);
654template <
typename Iterator>
663NEFORCE_END_NAMESPACE__
constexpr const T & median(const T &a, const T &b, const T &c, Compare comp) noexcept(noexcept(comp(a, b)))
返回三个值的中位数
NEFORCE_CONSTEXPR20 void adjust_heap(Iterator first, iter_difference_t< Iterator > hole_index, iter_difference_t< Iterator > len, T value, Compare comp)
堆调整辅助函数
NEFORCE_CONSTEXPR20 void sort_heap(Iterator first, Iterator last, Compare comp)
将堆转换为有序序列
NEFORCE_CONSTEXPR20 void make_heap(Iterator first, Iterator last, Compare comp)
创建堆
NEFORCE_INLINE17 constexpr bool is_invocable_v
is_invocable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
constexpr Iterator lomuto_partition(Iterator first, Iterator last, const T &pivot, Compare comp)
Lomuto分区算法
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_backward_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)
检查范围是否已排序
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)
查找首个破坏排序的元素
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)
快速排序
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)
归并排序
void insertion_sort(Iterator first, Iterator last, Compare comp)
插入排序