NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
sort.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_SORT_HPP__
2#define NEFORCE_CORE_ALGORITHM_SORT_HPP__
3
11
16NEFORCE_BEGIN_NAMESPACE__
17
23
124
136template <typename Iterator, typename Compare>
137bool is_sorted(Iterator first, Iterator last, Compare comp) {
138 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
139 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
140
141 if (first == last) {
142 return true;
143 }
144 Iterator next = _NEFORCE next(first);
145 for (; next != last; ++first, ++next) {
146 if (comp(*next, *first)) {
147 return false;
148 }
149 }
150 return true;
151}
152
160template <typename Iterator>
161bool is_sorted(Iterator first, Iterator last) {
162 return is_sorted(first, last, _NEFORCE less<>());
163}
164
176template <typename Iterator, typename Compare>
177Iterator is_sorted_until(Iterator first, Iterator last, Compare comp) {
178 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
179 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
180
181 if (first == last) {
182 return last;
183 }
184 Iterator next = _NEFORCE next(first);
185 for (; next != last; ++first, ++next) {
186 if (comp(*next, *first)) {
187 return next;
188 }
189 }
190 return last;
191}
192
200template <typename Iterator>
201Iterator is_sorted_until(Iterator first, Iterator last) {
202 return is_sorted_until(first, last, _NEFORCE less<>());
203}
204
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");
222
223 if (first == last) {
224 return;
225 }
226 Iterator end = last;
227 --end;
228 auto revend = _NEFORCE make_reverse_iterator(first);
229 auto revstart = _NEFORCE make_reverse_iterator(end);
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) {
234 Iterator next = it;
235 ++next;
236 if (comp(*next, *it)) {
237 _NEFORCE iter_swap(it, next);
238 not_finished = true;
239 }
240 }
241 if (!not_finished) {
242 break;
243 }
244 }
245}
246
253template <typename Iterator>
254NEFORCE_CONSTEXPR20 void bubble_sort(Iterator first, Iterator last) {
255 return _NEFORCE bubble_sort(first, last, _NEFORCE less<>());
256}
257
272template <typename Iterator, typename Compare>
273NEFORCE_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last, Compare comp) {
274 static_assert(is_ranges_bid_iter_v<Iterator>, "Iterator must be bidirectional_iterator");
275 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
276
277 if (first == last) {
278 return;
279 }
280 bool swapped = true;
281 Iterator left = first;
282 Iterator right = last;
283 --right;
284 while (swapped) {
285 swapped = false;
286 for (Iterator i = left; i != right; ++i) {
287 Iterator next = i;
288 ++next;
289 if (comp(*next, *i)) {
290 _NEFORCE iter_swap(i, next);
291 swapped = true;
292 }
293 }
294 if (!swapped) {
295 break;
296 }
297 --right;
298 swapped = false;
299 for (Iterator i = right; i != left; --i) {
300 Iterator prev = i;
301 --prev;
302 if (comp(*i, *prev)) {
303 _NEFORCE iter_swap(i, prev);
304 swapped = true;
305 }
306 }
307 ++left;
308 }
309}
310
317template <typename Iterator>
318NEFORCE_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last) {
319 return _NEFORCE cocktail_sort(first, last, _NEFORCE less<>());
320}
321
336template <typename Iterator, typename Compare>
337NEFORCE_CONSTEXPR20 void select_sort(Iterator first, Iterator last, Compare comp) {
338 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
339 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
340
341 if (first == last) {
342 return;
343 }
344 for (Iterator i = first; i != last; ++i) {
345 Iterator min = i;
346 Iterator j = i;
347 ++j;
348 for (; j != last; ++j) {
349 if (comp(*j, *min)) {
350 min = j;
351 }
352 }
353 _NEFORCE iter_swap(i, min);
354 }
355}
356
363template <typename Iterator>
364NEFORCE_CONSTEXPR20 void select_sort(Iterator first, Iterator last) {
365 return _NEFORCE select_sort(first, last, _NEFORCE less<>());
366}
367
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) {
384 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
385 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
386
387 if (first == last) {
388 return;
389 }
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) {
393 iter_value_t<Iterator> temp = *i;
394 Iterator j;
395 for (j = i; j >= first + gap && comp(temp, *(j - gap)); j -= gap) {
396 *j = *(j - gap);
397 }
398 *j = _NEFORCE move(temp);
399 }
400 }
401}
402
409template <typename Iterator>
410NEFORCE_CONSTEXPR20 void shell_sort(Iterator first, Iterator last) {
411 return _NEFORCE shell_sort(first, last, _NEFORCE less<>());
412}
413
431template <typename Iterator, typename Compare>
432void merge_sort(Iterator first, Iterator last, Compare comp) {
433 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
434
435 const auto n = _NEFORCE distance(first, last);
436 if (n < 2) {
437 return;
438 }
439 Iterator mid = first + n / 2;
440 _NEFORCE merge_sort(first, mid, comp);
441 _NEFORCE merge_sort(mid, last, comp);
442 _NEFORCE inplace_merge(first, mid, last, comp);
443}
444
451template <typename Iterator>
452void merge_sort(Iterator first, Iterator last) {
453 return _NEFORCE merge_sort(first, last, _NEFORCE less<>());
454}
455
471template <typename Iterator, typename Compare>
472void partial_sort(Iterator first, Iterator middle, Iterator last, Compare comp) {
473 if (first == middle) {
474 return;
475 }
476 _NEFORCE make_heap(first, middle, comp);
477 for (Iterator i = middle; i < last; ++i) {
478 if (comp(*i, *first)) {
479 inner::pop_heap_aux(first, middle, i, *i, comp);
480 }
481 }
482 _NEFORCE sort_heap(first, middle, comp);
483}
484
492template <typename Iterator>
493void partial_sort(Iterator first, Iterator middle, Iterator last) {
494 return _NEFORCE partial_sort(first, middle, last, _NEFORCE less<>());
495}
496
513template <typename Iterator1, typename Iterator2, typename Compare>
514Iterator2 partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last,
515 Compare comp) {
516 static_assert(is_ranges_input_iter_v<Iterator1>, "Iterator must be input_iterator");
517
518 if (result_first == result_last) {
519 return result_last;
520 }
521 Iterator2 result_real_last = result_first;
522 while (first != last && result_real_last != result_last) {
523 *result_real_last = *first;
524 ++result_real_last;
525 ++first;
526 }
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);
531 }
532 ++first;
533 }
534 _NEFORCE sort_heap(result_first, result_real_last, comp);
535 return result_real_last;
536}
537
548template <typename Iterator1, typename Iterator2>
549Iterator2 partial_sort_copy(Iterator1 first, Iterator1 last, Iterator2 result_first, Iterator2 result_last) {
550 return _NEFORCE partial_sort_copy(first, last, result_first, result_last, _NEFORCE less<>());
551}
552
554NEFORCE_BEGIN_INNER__
555
567template <typename Iterator, typename T, typename Compare>
568void __insertion_sort_aux(Iterator last, T value, Compare comp) {
569 Iterator next = last;
570 --next;
571 while (comp(value, *next)) {
572 *last = *next;
573 last = next;
574 --next;
575 }
576 *last = value;
577}
578
579NEFORCE_END_INNER__
581
597template <typename Iterator, typename Compare>
598void insertion_sort(Iterator first, Iterator last, Compare comp) {
599 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
600 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
601
602 if (first == last) {
603 return;
604 }
605 for (Iterator i = first + 1; i != last; ++i) {
606 iter_value_t<Iterator> value = *i;
607 if (comp(value, *first)) {
608 _NEFORCE copy_backward(first, i, i + 1);
609 *first = value;
610 } else {
611 inner::__insertion_sort_aux(i, value, comp);
612 }
613 }
614}
615
622template <typename Iterator>
623void insertion_sort(Iterator first, Iterator last) {
624 return _NEFORCE insertion_sort(first, last, _NEFORCE less<>());
625}
626
645template <typename Iterator, typename Compare>
646void introspective_sort(Iterator first, Iterator last, int depth_limit, Compare comp) {
647 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
648
649 while (first < last) {
650 if (depth_limit == 0) {
651 _NEFORCE partial_sort(first, last, last, comp);
652 return;
653 }
654 --depth_limit;
655
656 Iterator cut = _NEFORCE lomuto_partition(first, last, comp);
657 if (cut - first < last - cut) {
658 _NEFORCE introspective_sort(first, cut, depth_limit, comp);
659 first = cut + 1;
660 } else {
661 _NEFORCE introspective_sort(cut + 1, last, depth_limit, comp);
662 last = cut;
663 }
664 }
665}
666
674template <typename Iterator>
675void introspective_sort(Iterator first, Iterator last, int depth_limit) {
676 return _NEFORCE introspective_sort(first, last, depth_limit, _NEFORCE less<>());
677}
678
698template <typename Iterator, typename Compare>
699void quick_sort(Iterator first, Iterator last, Compare comp) {
700 if (first < last) {
701 Iterator cut = _NEFORCE lomuto_partition(first, last, comp);
702 _NEFORCE quick_sort(first, cut, comp);
703 _NEFORCE quick_sort(cut + 1, last, comp);
704 }
705}
706
713template <typename Iterator>
714void quick_sort(Iterator first, Iterator last) {
715 return _NEFORCE quick_sort(first, last, _NEFORCE less<>());
716}
717
719NEFORCE_BEGIN_INNER__
720
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) {
736 _NEFORCE partial_sort(first, last, last, comp);
737 return;
738 }
739 --depth_limit;
740
741 Iterator cut = _NEFORCE lomuto_partition(first, last, comp);
742
743 if (cut - first < last - cut) {
744 inner::__intro_sort_dispatch(first, cut, depth_limit, comp);
745 first = cut + 1;
746 } else {
747 inner::__intro_sort_dispatch(cut + 1, last, depth_limit, comp);
748 last = cut;
749 }
750 }
751}
752
760NEFORCE_CONST_FUNCTION constexpr int __log2_int(int x) noexcept {
761 int k = 0;
762 for (; x > 1; x >>= 1) {
763 ++k;
764 }
765 return k;
766}
767
768NEFORCE_END_INNER__
770
788template <typename Iterator, typename Compare>
789void sort(Iterator first, Iterator last, Compare comp) {
790 if (first == last) {
791 return;
792 }
793
794 inner::__intro_sort_dispatch(first, last, inner::__log2_int(last - first) * 2, comp);
795 constexpr size_t threshhold = MEMORY_ALIGN_THRESHHOLD;
796
797 if (last - first > threshhold) {
798 _NEFORCE insertion_sort(first, first + threshhold, comp);
799 for (Iterator i = first + threshhold; i != last; ++i) {
800 inner::__insertion_sort_aux(i, *i, comp);
801 }
802 } else {
803 _NEFORCE insertion_sort(first, last, comp);
804 }
805}
806
813template <typename Iterator>
814void sort(Iterator first, Iterator last) {
815 return _NEFORCE sort(first, last, _NEFORCE less<>());
816}
817
832template <typename Iterator, typename Compare>
833NEFORCE_CONSTEXPR20 void tim_sort(Iterator first, Iterator last, Compare comp) {
834 if (first == last) {
835 return;
836 }
837
838 constexpr int min_merge = 32;
839 const auto n = _NEFORCE distance(first, last);
840
841 if (n > 0) {
842 Iterator i = first;
843 while (i < last) {
844 auto step = _NEFORCE min(static_cast<decltype(n)>(min_merge), last - i);
845 Iterator end = _NEFORCE next(i, step);
846 _NEFORCE insertion_sort(i, end, comp);
847 i = end;
848 }
849 }
850
851 for (int size = min_merge; size < n; size *= 2) {
852 for (Iterator left = first; left < last;) {
853 const auto remaining = _NEFORCE distance(left, last);
854 if (remaining <= size) {
855 break;
856 }
857
858 Iterator mid = _NEFORCE next(left, size);
859 Iterator right = _NEFORCE next(left, _NEFORCE min(2 * size, static_cast<int>(remaining)));
860
861 if (mid < right) {
862 _NEFORCE inplace_merge(left, mid, right, comp);
863 }
864 left = right;
865 }
866 }
867}
868
875template <typename Iterator>
876NEFORCE_CONSTEXPR20 void tim_sort(Iterator first, Iterator last) {
877 return _NEFORCE tim_sort(first, last, _NEFORCE less<>());
878}
879
893template <typename Iterator, typename Compare>
894void nth_element(Iterator first, Iterator nth, Iterator last, Compare comp) {
895 while (last - first > 3) {
896 Iterator cut = _NEFORCE lomuto_partition(first, last, comp);
897 if (cut <= nth) {
898 first = cut + 1;
899 } else {
900 last = cut;
901 }
902 }
903 _NEFORCE insertion_sort(first, last, comp);
904}
905
913template <typename Iterator>
914void nth_element(Iterator first, Iterator nth, Iterator last) {
915 return _NEFORCE nth_element(first, nth, last, _NEFORCE less<>());
916}
917 // SortAlgorithms
919 // StandardAlgorithms
921
922NEFORCE_END_NAMESPACE__
923#endif // NEFORCE_CORE_ALGORITHM_SORT_HPP__
比较算法
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()))
获取容器的结束迭代器
堆算法
合并算法
分区算法
小于比较仿函数