1#ifndef NEFORCE_CORE_ALGORITHM_EXT_SORT_HPP__
2#define NEFORCE_CORE_ALGORITHM_EXT_SORT_HPP__
13NEFORCE_BEGIN_NAMESPACE__
41template <
typename Iterator,
typename Compare>
42NEFORCE_CONSTEXPR20
void bubble_sort(Iterator first, Iterator last, Compare comp) {
43 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
52 for (
auto iter = revstart; iter != revend; ++iter) {
53 bool not_finished =
false;
54 Iterator curend = iter.base();
55 for (Iterator it = first; it != curend; ++it) {
58 if (comp(*
next, *it)) {
75template <
typename Iterator>
76NEFORCE_CONSTEXPR20
void bubble_sort(Iterator first, Iterator last) {
94template <
typename Iterator,
typename Compare>
95NEFORCE_CONSTEXPR20
void cocktail_sort(Iterator first, Iterator last, Compare comp) {
97 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
103 Iterator left = first;
104 Iterator right = last;
108 for (Iterator i = left; i != right; ++i) {
111 if (comp(*
next, *i)) {
121 for (Iterator i = right; i != left; --i) {
124 if (comp(*i, *
prev)) {
139template <
typename Iterator>
158template <
typename Iterator,
typename Compare>
159NEFORCE_CONSTEXPR20
void select_sort(Iterator first, Iterator last, Compare comp) {
161 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
166 for (Iterator i = first; i != last; ++i) {
170 for (; j != last; ++j) {
171 if (comp(*j, *
min)) {
185template <
typename Iterator>
186NEFORCE_CONSTEXPR20
void select_sort(Iterator first, Iterator last) {
204template <
typename Iterator,
typename Compare, enable_if_t<is_ranges_rnd_iter_v<Iterator>,
int> = 0>
205NEFORCE_CONSTEXPR20
void shell_sort(Iterator first, Iterator last, Compare comp) {
207 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
212 auto dist = _NEFORCE
distance(first, last);
213 for (
auto gap = dist / 2; gap > 0; gap /= 2) {
214 for (Iterator i = first + gap; i < last; ++i) {
217 for (j = i; j >= first + gap && comp(temp, *(j - gap)); j -= gap) {
220 *j = _NEFORCE
move(temp);
231template <
typename Iterator>
232NEFORCE_CONSTEXPR20
void shell_sort(Iterator first, Iterator last) {
252template <
typename Iterator,
typename Compare,
typename IndexMapper>
253NEFORCE_CONSTEXPR20
void counting_sort(Iterator first, Iterator last, Compare comp, IndexMapper mapper) {
255 static_assert(
is_invocable_v<Compare,
decltype(*first),
decltype(*first)>,
"Compare must be invocable");
256 static_assert(
is_invocable_v<IndexMapper,
decltype(*first)>,
"IndexMapper must be invocable");
262 auto min_val = mapper(*min_max.first);
263 auto max_val = mapper(*min_max.second);
264 const auto range =
static_cast<size_t>(max_val - min_val + 1);
267 for (Iterator it = first; it != last; ++it) {
268 auto value = mapper(*it);
269 if (value < min_val || value > max_val) {
270 NEFORCE_THROW_EXCEPTION(
iterator_exception(
"element out of range for counting sort."));
272 ++
count[
static_cast<size_t>(value - min_val)];
275 for (
size_t i = 1; i <
count.size(); ++i) {
283 auto value = mapper(*rit);
284 const auto index =
static_cast<size_t>(value - min_val);
285 size_t position = --
count[index];
286 sorted[position] = *rit;
297template <
typename Iterator>
315template <
typename Iterator>
321 T min_val = *min_max.
first;
322 T max_val = *min_max.
second;
323 T range = max_val - min_val + 1;
326 for (Iterator it = first; it != last; ++it) {
327 ++bucket[*it - min_val];
330 Iterator index = first;
332 for (
size_t i = 0; i < bucket.
size(); ++i) {
333 while (bucket[i] > 0) {
334 *index++ =
static_cast<T
>(i + min_val);
346template <
typename Iterator>
352 T min_val = *min_max.
first;
353 T max_val = *min_max.
second;
354 T range = max_val - min_val + 1;
357 for (Iterator it = first; it != last; ++it) {
358 ++bucket[*it - min_val];
361 Iterator index = first;
363 for (
size_t i = bucket.
size(); i-- > 0;) {
364 while (bucket[i] > 0) {
365 *index++ =
static_cast<T
>(i + min_val);
377template <
typename Iterator>
378NEFORCE_CONSTEXPR20
void bucket_sort(Iterator first, Iterator last) {
385template <
typename Iterator>
386int __max_bit_aux(Iterator first, Iterator last) {
387 auto max_num = *_NEFORCE
max_element(first, last, [](
const auto& a,
const auto& b) ->
bool {
return a < b; });
389 while (max_num > 0) {
391 max_num = max_num / 10;
397int __get_number_aux(T num, T d) {
399 for (T i = 1; i < d; ++i) {
422template <
typename Iterator,
typename Mapper>
423NEFORCE_CONSTEXPR20
void radix_sort_less(Iterator first, Iterator last, Mapper mapper) {
425 static_assert(
is_invocable_v<Mapper,
decltype(*first)>,
"Mapper must be invocable");
432 auto length = _NEFORCE
distance(first, last);
438 for (
auto& value: mapped_values) {
439 value = mapper(*it++);
442 for (
int d = 1; d <= inner::__max_bit_aux(mapped_values.
begin(), mapped_values.
end()); ++d) {
444 for (
const auto& num: mapped_values) {
445 ++
count[inner::__get_number_aux(num, d)];
448 for (
size_t i = 1; i <
count.size(); ++i) {
451 for (
auto iter = mapped_values.rbegin(); iter != mapped_values.rend(); ++iter) {
452 const int k = inner::__get_number_aux(*iter, d);
453 bucket[--
count[k]] = *(first + _NEFORCE
distance(mapped_values.begin(), iter.base() - 1));
457 for (
const auto& value: bucket) {
462 for (
auto& value: mapped_values) {
463 value = mapper(*it++);
476template <
typename Iterator,
typename Mapper>
479 static_assert(
is_invocable_v<Mapper,
decltype(*first)>,
"Mapper must be invocable");
492 for (
auto& value: mapped_values) {
493 value = mapper(*it++);
495 for (
int d = 1; d <= inner::__max_bit_aux(mapped_values.
begin(), mapped_values.
end()); ++d) {
497 for (
const auto& num: mapped_values) {
498 ++
count[inner::__get_number_aux(num, d)];
501 for (
size_t i =
count.size() - 1; i > 0; --i) {
505 for (
auto iter = mapped_values.rbegin(); iter != mapped_values.rend(); ++iter) {
506 const int k = inner::__get_number_aux(*iter, d);
507 bucket[--
count[k]] = *(first + _NEFORCE
distance(mapped_values.begin(), iter.base() - 1));
511 for (
const auto& value: bucket) {
516 for (
auto& value: mapped_values) {
517 value = mapper(*it++);
530template <
typename Iterator,
typename Mapper = _NEFORCE
identity<iter_value_t<Iterator>>>
531NEFORCE_CONSTEXPR20
void radix_sort(Iterator first, Iterator last, Mapper mapper = Mapper()) {
548template <
typename Iterator>
549NEFORCE_CONSTEXPR20
void smooth_sort(Iterator first, Iterator last) {
568template <
typename Iterator,
typename Compare>
569NEFORCE_CONSTEXPR20
void tim_sort(Iterator first, Iterator last, Compare comp) {
570 constexpr int min_merge = 32;
572 for (Iterator i = first; i < last; i += min_merge) {
573 Iterator
end = _NEFORCE
min(i + min_merge, last);
577 for (Iterator left = first; left < last; left += 2 *
size) {
578 Iterator mid = left +
size;
579 Iterator right = _NEFORCE
min(left + 2 *
size, last);
593template <
typename Iterator>
594NEFORCE_CONSTEXPR20
void tim_sort(Iterator first, Iterator last) {
614template <
typename Iterator,
typename Compare>
616 while (!_NEFORCE
is_sorted(first, last, comp)) {
629template <
typename Iterator>
638NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator end() noexcept
获取结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept
获取当前元素数量
constexpr pair< Iterator, Iterator > minmax_element(Iterator first, Iterator last, Compare comp)
同时查找范围中的最小和最大元素
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
constexpr Iterator max_element(Iterator first, Iterator last, Compare comp)
查找范围中的最大元素
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
NEFORCE_INLINE17 constexpr bool is_invocable_v
is_invocable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=-1)
获取迭代器的前一个位置
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
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
void sort_leonardo_heap(Iterator first, Iterator last)
使用莱昂纳多堆进行排序
void make_leonardo_heap(Iterator first, Iterator last)
构建莱昂纳多堆
NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
NEFORCE_NODISCARD constexpr reverse_iterator< Iterator > make_reverse_iterator(Iterator it) noexcept(is_nothrow_move_constructible_v< Iterator >)
创建反向迭代器
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
void shuffle(Iterator first, Iterator last)
随机重排序列
NEFORCE_CONSTEXPR20 void select_sort(Iterator first, Iterator last, Compare comp)
选择排序
bool is_sorted(Iterator first, Iterator last, Compare comp)
检查范围是否已排序
NEFORCE_CONSTEXPR20 void radix_sort(Iterator first, Iterator last, Mapper mapper=Mapper())
基数排序(默认升序)
NEFORCE_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last, Compare comp)
鸡尾酒排序(双向冒泡排序)
NEFORCE_CONSTEXPR20 void radix_sort_greater(Iterator first, Iterator last, Mapper mapper)
基数排序(降序)
NEFORCE_CONSTEXPR20 void bucket_sort_less(Iterator first, Iterator last)
桶排序(升序)
NEFORCE_CONSTEXPR20 void counting_sort(Iterator first, Iterator last, Compare comp, IndexMapper mapper)
计数排序
NEFORCE_CONSTEXPR20 void bucket_sort_greater(Iterator first, Iterator last)
桶排序(降序)
NEFORCE_CONSTEXPR20 void tim_sort(Iterator first, Iterator last, Compare comp)
Tim排序
NEFORCE_CONSTEXPR20 void smooth_sort(Iterator first, Iterator last)
平滑排序
NEFORCE_CONSTEXPR20 void bucket_sort(Iterator first, Iterator last)
桶排序(默认升序)
NEFORCE_CONSTEXPR20 void shell_sort(Iterator first, Iterator last, Compare comp)
希尔排序
void insertion_sort(Iterator first, Iterator last, Compare comp)
插入排序
NEFORCE_CONSTEXPR20 void radix_sort_less(Iterator first, Iterator last, Mapper mapper)
基数排序(升序)
NEFORCE_CONSTEXPR20 void bubble_sort(Iterator first, Iterator last, Compare comp)
冒泡排序
void monkey_sort(Iterator first, Iterator last, Compare comp)
猴子排序
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小