NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
ext_sort.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_EXT_SORT_HPP__
2#define NEFORCE_CORE_ALGORITHM_EXT_SORT_HPP__
3
11
13NEFORCE_BEGIN_NAMESPACE__
14
20
26
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");
44
45 if (first == last) {
46 return;
47 }
48 Iterator end = last;
49 --end;
50 auto revend = _NEFORCE make_reverse_iterator(first);
51 auto revstart = _NEFORCE make_reverse_iterator(end);
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) {
56 Iterator next = it;
57 ++next;
58 if (comp(*next, *it)) {
59 _NEFORCE iter_swap(it, next);
60 not_finished = true;
61 }
62 }
63 if (!not_finished) {
64 break;
65 }
66 }
67}
68
75template <typename Iterator>
76NEFORCE_CONSTEXPR20 void bubble_sort(Iterator first, Iterator last) {
77 return _NEFORCE bubble_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
78}
79
94template <typename Iterator, typename Compare>
95NEFORCE_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last, Compare comp) {
96 static_assert(is_ranges_bid_iter_v<Iterator>, "Iterator must be bidirectional_iterator");
97 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
98
99 if (first == last) {
100 return;
101 }
102 bool swapped = true;
103 Iterator left = first;
104 Iterator right = last;
105 --right;
106 while (swapped) {
107 swapped = false;
108 for (Iterator i = left; i != right; ++i) {
109 Iterator next = i;
110 ++next;
111 if (comp(*next, *i)) {
112 _NEFORCE iter_swap(i, next);
113 swapped = true;
114 }
115 }
116 if (!swapped) {
117 break;
118 }
119 --right;
120 swapped = false;
121 for (Iterator i = right; i != left; --i) {
122 Iterator prev = i;
123 --prev;
124 if (comp(*i, *prev)) {
125 _NEFORCE iter_swap(i, prev);
126 swapped = true;
127 }
128 }
129 ++left;
130 }
131}
132
139template <typename Iterator>
140NEFORCE_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last) {
141 return _NEFORCE cocktail_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
142}
143
158template <typename Iterator, typename Compare>
159NEFORCE_CONSTEXPR20 void select_sort(Iterator first, Iterator last, Compare comp) {
160 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
161 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
162
163 if (first == last) {
164 return;
165 }
166 for (Iterator i = first; i != last; ++i) {
167 Iterator min = i;
168 Iterator j = i;
169 ++j;
170 for (; j != last; ++j) {
171 if (comp(*j, *min)) {
172 min = j;
173 }
174 }
175 _NEFORCE iter_swap(i, min);
176 }
177}
178
185template <typename Iterator>
186NEFORCE_CONSTEXPR20 void select_sort(Iterator first, Iterator last) {
187 return _NEFORCE select_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
188}
189
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) {
206 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
207 static_assert(is_invocable_v<Compare, decltype(*first), decltype(*first)>, "Compare must be invocable");
208
209 if (first == last) {
210 return;
211 }
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) {
215 iter_value_t<Iterator> temp = *i;
216 Iterator j;
217 for (j = i; j >= first + gap && comp(temp, *(j - gap)); j -= gap) {
218 *j = *(j - gap);
219 }
220 *j = _NEFORCE move(temp);
221 }
222 }
223}
224
231template <typename Iterator>
232NEFORCE_CONSTEXPR20 void shell_sort(Iterator first, Iterator last) {
233 return _NEFORCE shell_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
234}
235
252template <typename Iterator, typename Compare, typename IndexMapper>
253NEFORCE_CONSTEXPR20 void counting_sort(Iterator first, Iterator last, Compare comp, IndexMapper mapper) {
254 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
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");
257
258 if (first == last) {
259 return;
260 }
261 auto min_max = _NEFORCE minmax_element(first, last, comp);
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);
265 vector<int> count(range, 0);
266
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."));
271 }
272 ++count[static_cast<size_t>(value - min_val)];
273 }
274
275 for (size_t i = 1; i < count.size(); ++i) {
276 count[i] += count[i - 1];
277 }
278
279 vector<iter_value_t<Iterator>> sorted(_NEFORCE distance(first, last));
280 auto bound = _NEFORCE make_reverse_iterator(first);
281
282 for (auto rit = _NEFORCE make_reverse_iterator(last); rit != bound; ++rit) {
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;
287 }
288 _NEFORCE copy(sorted.begin(), sorted.end(), first);
289}
290
297template <typename Iterator>
298NEFORCE_CONSTEXPR20 void counting_sort(Iterator first, Iterator last) {
299 _NEFORCE counting_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>(),
300 _NEFORCE identity<iter_value_t<Iterator>>());
301}
302
315template <typename Iterator>
316NEFORCE_CONSTEXPR20 void bucket_sort_less(Iterator first, Iterator last) {
317 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
318
319 using T = iter_value_t<Iterator>;
320 pair<Iterator, Iterator> min_max = _NEFORCE minmax_element(first, last);
321 T min_val = *min_max.first;
322 T max_val = *min_max.second;
323 T range = max_val - min_val + 1;
324 vector<size_t> bucket(range, 0);
325
326 for (Iterator it = first; it != last; ++it) {
327 ++bucket[*it - min_val];
328 }
329
330 Iterator index = first;
331
332 for (size_t i = 0; i < bucket.size(); ++i) {
333 while (bucket[i] > 0) {
334 *index++ = static_cast<T>(i + min_val);
335 --bucket[i];
336 }
337 }
338}
339
346template <typename Iterator>
347NEFORCE_CONSTEXPR20 void bucket_sort_greater(Iterator first, Iterator last) {
348 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
349
350 using T = iter_value_t<Iterator>;
351 pair<Iterator, Iterator> min_max = _NEFORCE minmax_element(first, last);
352 T min_val = *min_max.first;
353 T max_val = *min_max.second;
354 T range = max_val - min_val + 1;
355 vector<size_t> bucket(range, 0);
356
357 for (Iterator it = first; it != last; ++it) {
358 ++bucket[*it - min_val];
359 }
360
361 Iterator index = first;
362
363 for (size_t i = bucket.size(); i-- > 0;) {
364 while (bucket[i] > 0) {
365 *index++ = static_cast<T>(i + min_val);
366 --bucket[i];
367 }
368 }
369}
370
377template <typename Iterator>
378NEFORCE_CONSTEXPR20 void bucket_sort(Iterator first, Iterator last) {
379 _NEFORCE bucket_sort_less(first, last);
380}
381
383NEFORCE_BEGIN_INNER__
384
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; });
388 int p = 0;
389 while (max_num > 0) {
390 p++;
391 max_num = max_num / 10;
392 }
393 return p;
394}
395
396template <typename T>
397int __get_number_aux(T num, T d) {
398 int p = 1;
399 for (T i = 1; i < d; ++i) {
400 p *= 10;
401 }
402 return num / p % 10;
403}
404
405NEFORCE_END_INNER__
407
422template <typename Iterator, typename Mapper>
423NEFORCE_CONSTEXPR20 void radix_sort_less(Iterator first, Iterator last, Mapper mapper) {
424 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
425 static_assert(is_invocable_v<Mapper, decltype(*first)>, "Mapper must be invocable");
426
427 if (first == last) {
428 return;
429 }
430 using Mapped = remove_reference_t<decltype(mapper(*first))>;
431
432 auto length = _NEFORCE distance(first, last);
433 vector<Mapped> mapped_values(length);
434 vector<iter_value_t<Iterator>> bucket(length);
435 vector<int> count(10);
436 Iterator it = first;
437
438 for (auto& value: mapped_values) {
439 value = mapper(*it++);
440 }
441
442 for (int d = 1; d <= inner::__max_bit_aux(mapped_values.begin(), mapped_values.end()); ++d) {
443 _NEFORCE fill(count.begin(), count.end(), 0);
444 for (const auto& num: mapped_values) {
445 ++count[inner::__get_number_aux(num, d)];
446 }
447
448 for (size_t i = 1; i < count.size(); ++i) {
449 count[i] += count[i - 1];
450 }
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));
454 }
455
456 it = first;
457 for (const auto& value: bucket) {
458 *it++ = value;
459 }
460
461 it = first;
462 for (auto& value: mapped_values) {
463 value = mapper(*it++);
464 }
465 }
466}
467
476template <typename Iterator, typename Mapper>
477NEFORCE_CONSTEXPR20 void radix_sort_greater(Iterator first, Iterator last, Mapper mapper) {
478 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
479 static_assert(is_invocable_v<Mapper, decltype(*first)>, "Mapper must be invocable");
480
481 if (first == last) {
482 return;
483 }
484 using Mapped = remove_cvref_t<decltype(mapper(*first))>;
485
486 iter_difference_t<Iterator> length = _NEFORCE distance(first, last);
487 vector<Mapped> mapped_values(length);
488 vector<iter_value_t<Iterator>> bucket(length);
489 vector<int> count(10);
490 Iterator it = first;
491
492 for (auto& value: mapped_values) {
493 value = mapper(*it++);
494 }
495 for (int d = 1; d <= inner::__max_bit_aux(mapped_values.begin(), mapped_values.end()); ++d) {
496 _NEFORCE fill(count.begin(), count.end(), 0);
497 for (const auto& num: mapped_values) {
498 ++count[inner::__get_number_aux(num, d)];
499 }
500
501 for (size_t i = count.size() - 1; i > 0; --i) {
502 count[i - 1] += count[i];
503 }
504
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));
508 }
509
510 it = first;
511 for (const auto& value: bucket) {
512 *it++ = value;
513 }
514
515 it = first;
516 for (auto& value: mapped_values) {
517 value = mapper(*it++);
518 }
519 }
520}
521
530template <typename Iterator, typename Mapper = _NEFORCE identity<iter_value_t<Iterator>>>
531NEFORCE_CONSTEXPR20 void radix_sort(Iterator first, Iterator last, Mapper mapper = Mapper()) {
532 _NEFORCE radix_sort_less(first, last, mapper);
533}
534
548template <typename Iterator>
549NEFORCE_CONSTEXPR20 void smooth_sort(Iterator first, Iterator last) {
550 _NEFORCE make_leonardo_heap(first, last);
551 _NEFORCE sort_leonardo_heap(first, last);
552}
553
568template <typename Iterator, typename Compare>
569NEFORCE_CONSTEXPR20 void tim_sort(Iterator first, Iterator last, Compare comp) {
570 constexpr int min_merge = 32;
571 iter_difference_t<Iterator> n = _NEFORCE distance(first, last);
572 for (Iterator i = first; i < last; i += min_merge) {
573 Iterator end = _NEFORCE min(i + min_merge, last);
574 _NEFORCE insertion_sort(i, end, comp);
575 }
576 for (int size = min_merge; size < n; size *= 2) {
577 for (Iterator left = first; left < last; left += 2 * size) {
578 Iterator mid = left + size;
579 Iterator right = _NEFORCE min(left + 2 * size, last);
580 if (mid < right) {
581 _NEFORCE inplace_merge(left, mid, right, comp);
582 }
583 }
584 }
585}
586
593template <typename Iterator>
594NEFORCE_CONSTEXPR20 void tim_sort(Iterator first, Iterator last) {
595 return _NEFORCE tim_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
596}
597
614template <typename Iterator, typename Compare>
615void monkey_sort(Iterator first, Iterator last, Compare comp) {
616 while (!_NEFORCE is_sorted(first, last, comp)) {
617 _NEFORCE shuffle(first, last);
618 }
619}
620
629template <typename Iterator>
630void monkey_sort(Iterator first, Iterator last) {
631 return _NEFORCE monkey_sort(first, last, _NEFORCE less<iter_value_t<Iterator>>());
632}
633 // SortAlgorithms
635 // StandardAlgorithms
637
638NEFORCE_END_NAMESPACE__
639#endif // NEFORCE_CORE_ALGORITHM_EXT_SORT_HPP__
动态大小数组容器
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()))
获取容器的大小
莱昂纳多堆算法实现
恒等仿函数
指针或迭代器行为异常
小于比较仿函数
存储两个值的元组对
T2 second
第二个元素
T1 first
第一个元素