MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
ext_sort.hpp
1#ifndef MSTL_CORE_ALGORITHM_EXT_SORT_HPP__
2#define MSTL_CORE_ALGORITHM_EXT_SORT_HPP__
3#include "leonardo_heap.hpp"
5
6// bubble sort : Ot(N)~(N^2) Om(1) stable
7template <typename Iterator, typename Compare, enable_if_t<is_ranges_bid_iter_v<Iterator>, int> = 0>
8MSTL_CONSTEXPR20 void bubble_sort(Iterator first, Iterator last, Compare comp) {
9 if (first == last) return;
10 auto revend = _MSTL make_reverse_iterator(first);
11 auto revstart = _MSTL make_reverse_iterator(--last);
12 for (auto iter = revstart; iter != revend; ++iter) {
13 bool not_finished = false;
14 Iterator curend = iter.base();
15 for (Iterator it = first; it != curend; ++it) {
16 Iterator next = it;
17 ++next;
18 if (comp(*next, *it)) {
19 _MSTL iter_swap(it, next);
20 not_finished = true;
21 }
22 }
23 if (!not_finished) break;
24 }
25}
26
27template <typename Iterator>
28MSTL_CONSTEXPR20 void bubble_sort(Iterator first, Iterator last) {
29 return _MSTL bubble_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
30}
31
32// cocktail sort : Ot(N)~(N^2) Om(1) stable
33template <typename Iterator, typename Compare, enable_if_t<is_ranges_bid_iter_v<Iterator>, int> = 0>
34MSTL_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last, Compare comp) {
35 if (first == last) return;
36 bool swapped = true;
37 Iterator left = first;
38 Iterator right = last;
39 --right;
40 while (swapped) {
41 swapped = false;
42 for (Iterator i = left; i != right; ++i) {
43 Iterator next = i;
44 ++next;
45 if (comp(*next, *i)) {
47 swapped = true;
48 }
49 }
50 if (!swapped) break;
51 --right;
52 swapped = false;
53 for (Iterator i = right; i != left; --i) {
54 Iterator prev = i;
55 --prev;
56 if (comp(*i, *prev)) {
58 swapped = true;
59 }
60 }
61 ++left;
62 }
63}
64
65template <typename Iterator>
66MSTL_CONSTEXPR20 void cocktail_sort(Iterator first, Iterator last) {
67 return _MSTL cocktail_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
68}
69
70// select sort : Ot(N^2) Om(1) unstable
71template <typename Iterator, typename Compare, enable_if_t<
73MSTL_CONSTEXPR20 void select_sort(Iterator first, Iterator last, Compare comp) {
74 if (first == last) return;
75 Iterator min;
76 for (Iterator i = first; i != last; ++i) {
77 min = i;
78 for (Iterator j = i + 1; j != last; ++j) {
79 if (comp(*j, *min)) {
80 min = j;
81 }
82 }
84 }
85}
86
87template <typename Iterator>
88MSTL_CONSTEXPR20 void select_sort(Iterator first, Iterator last) {
89 return _MSTL select_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
90}
91
92// shell sort : Ot(NlogN)~(N^2) Om(1) unstable
93template <typename Iterator, typename Compare, enable_if_t<
95MSTL_CONSTEXPR20 void shell_sort(Iterator first, Iterator last, Compare comp) {
96 if (first == last) return;
97 using Distance = iter_difference_t<Iterator>;
98 using T = iter_value_t<Iterator>;
99 Distance dist = _MSTL distance(first, last);
100 for (Distance gap = dist / 2; gap > 0; gap /= 2) {
101 for (Iterator i = first + gap; i < last; ++i) {
102 T temp = *i;
103 Iterator j;
104 for (j = i; j >= first + gap && comp(temp, *(j - gap)); j -= gap)
105 *j = *(j - gap);
106 *j = temp;
107 }
108 }
109}
110
111template <typename Iterator>
112MSTL_CONSTEXPR20 void shell_sort(Iterator first, Iterator last) {
113 return _MSTL shell_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
114}
115
116// counting sort : Ot(N + k) Om(k) stable
117template <typename Iterator, typename Compare, typename IndexMapper, enable_if_t<
119MSTL_CONSTEXPR20 void counting_sort(Iterator first, Iterator last, Compare comp, IndexMapper mapper) {
120 if (first == last) return;
121 auto min_max = _MSTL minmax_element(first, last, comp);
122 auto min_val = mapper(*min_max.first);
123 auto max_val = mapper(*min_max.second);
124 const auto range = static_cast<size_t>(max_val - min_val + 1);
125 vector<int> count(range, 0);
126
127 for (Iterator it = first; it != last; ++it) {
128 auto value = mapper(*it);
129 if (value < min_val || value > max_val) {
130 throw_exception(iterator_exception("element out of range for counting sort."));
131 }
132 ++count[static_cast<size_t>(value - min_val)];
133 }
134
135 for (size_t i = 1; i < count.size(); ++i)
136 count[i] += count[i - 1];
137
138 vector<iter_value_t<Iterator>> sorted(_MSTL distance(first, last));
139 auto bound = _MSTL make_reverse_iterator(first);
140
141 for (auto rit = _MSTL make_reverse_iterator(last); rit != bound; ++rit) {
142 auto value = mapper(*rit);
143 const auto index = static_cast<size_t>(value - min_val);
144 size_t position = --count[index];
145 sorted[position] = *rit;
146 }
147 _MSTL copy(sorted.begin(), sorted.end(), first);
148}
149
150template <typename Iterator>
151MSTL_CONSTEXPR20 void counting_sort(Iterator first, Iterator last) {
152 _MSTL counting_sort(first, last,
154}
155
156template <typename Iterator, enable_if_t<
158MSTL_CONSTEXPR20 void bucket_sort_less(Iterator first, Iterator last) {
159 using T = iter_value_t<Iterator>;
160 pair<Iterator, Iterator> min_max = _MSTL minmax_element(first, last);
161 T min_val = *min_max.first;
162 T max_val = *min_max.second;
163 T range = max_val - min_val + 1;
164 vector<size_t> bucket(range, 0);
165
166 for (Iterator it = first; it != last; ++it) {
167 ++bucket[*it - min_val];
168 }
169
170 Iterator index = first;
171
172 for (size_t i = 0; i < bucket.size(); ++i) {
173 while (bucket[i] > 0) {
174 *index++ = static_cast<T>(i + min_val);
175 --bucket[i];
176 }
177 }
178}
179
180template <typename Iterator, enable_if_t<
182MSTL_CONSTEXPR20 void bucket_sort_greater(Iterator first, Iterator last) {
183 using T = iter_value_t<Iterator>;
184 pair<Iterator, Iterator> min_max = _MSTL minmax_element(first, last);
185 T min_val = *min_max.first;
186 T max_val = *min_max.second;
187 T range = max_val - min_val + 1;
188 vector<size_t> bucket(range, 0);
189
190 for (Iterator it = first; it != last; ++it) {
191 ++bucket[*it - min_val];
192 }
193
194 Iterator index = first;
195
196 for (size_t i = bucket.size(); i-- > 0; ) {
197 while (bucket[i] > 0) {
198 *index++ = static_cast<T>(i + min_val);
199 --bucket[i];
200 }
201 }
202}
203
204// bucket sort : Ot(N + k)~(N^2) Om(N + k) stable
205template <typename Iterator>
206MSTL_CONSTEXPR20 void bucket_sort(Iterator first, Iterator last) {
207 _MSTL bucket_sort_less(first, last);
208}
209
211
212template <typename Iterator>
213int __max_bit_aux(Iterator first, Iterator last) {
214 auto max_num = *_MSTL max_element(first, last,
215 [](const auto& a, const auto& b) -> bool { return a < b; });
216 int p = 0;
217 while (max_num > 0) {
218 p++;
219 max_num = max_num / 10;
220 }
221 return p;
222}
223
224template <typename T>
225int __get_number_aux(T num, T d) {
226 int p = 1;
227 for (T i = 1; i < d; ++i)
228 p *= 10;
229 return num / p % 10;
230}
231
233
234template <typename Iterator, typename Mapper, enable_if_t<
236MSTL_CONSTEXPR20 void radix_sort_less(Iterator first, Iterator last, Mapper mapper) {
237 if (first == last) return;
238 using Mapped = remove_reference_t<decltype(mapper(*first))>;
239
240 iter_difference_t<Iterator> length = _MSTL distance(first, last);
241 vector<Mapped> mapped_values(length);
242 vector<iter_value_t<Iterator>> bucket(length);
243 vector<int> count(10);
244 Iterator it = first;
245
246 for (auto& value : mapped_values) {
247 value = mapper(*it++);
248 }
249
250 for (int d = 1; d <= _INNER __max_bit_aux(mapped_values.begin(), mapped_values.end()); ++d) {
251 _MSTL fill(count.begin(), count.end(), 0);
252 for(const auto& num : mapped_values) {
253 ++count[_INNER __get_number_aux(num, d)];
254 }
255
256 for (size_t i = 1; i < count.size(); ++i) {
257 count[i] += count[i - 1];
258 }
259 for (auto iter = mapped_values.rbegin(); iter != mapped_values.rend(); ++iter) {
260 const int k = _INNER __get_number_aux(*iter, d);
261 bucket[--count[k]] = *(first + _MSTL distance(mapped_values.begin(), iter.base() - 1));
262 }
263
264 it = first;
265 for(const auto& value : bucket) {
266 *it++ = value;
267 }
268 _MSTL transform(bucket.begin(), bucket.end(), mapped_values.begin(), mapper);
269 }
270}
271
272template <typename Iterator, typename Mapper, enable_if_t<
274MSTL_CONSTEXPR20 void radix_sort_greater(Iterator first, Iterator last, Mapper mapper) {
275 if (first == last) return;
276 using Mapped = remove_cvref_t<decltype(mapper(*first))>;
277
278 iter_difference_t<Iterator> length = _MSTL distance(first, last);
279 vector<Mapped> mapped_values(length);
280 vector<iter_value_t<Iterator>> bucket(length);
281 vector<int> count(10);
282 Iterator it = first;
283
284 for (auto& value : mapped_values) {
285 value = mapper(*it++);
286 }
287 for (int d = 1; d <= _INNER __max_bit_aux(mapped_values.begin(), mapped_values.end()); ++d) {
288 _MSTL fill(count.begin(), count.end(), 0);
289 for(const auto& num : mapped_values) {
290 ++count[_INNER __get_number_aux(*num, d)];
291 }
292
293 for (size_t i = count.size() - 1; i > 0; --i) {
294 count[i - 1] += count[i];
295 }
296
297 for (auto iter = mapped_values.rbegin(); iter != mapped_values.rend(); ++iter) {
298 const int k = _INNER __get_number_aux(*iter, d);
299 bucket[--count[k]] = *(first + _MSTL distance(mapped_values.begin(), iter.base() - 1));
300 }
301
302 it = first;
303 for(const auto& value : bucket) {
304 *it++ = value;
305 }
306 _MSTL transform(bucket.begin(), bucket.end(), mapped_values.begin(), mapper);
307 }
308}
309
310// radix sort : Ot(d(n + k)) Om(N + k) stable
311template <typename Iterator, typename Mapper = _MSTL identity<iter_value_t<Iterator>>>
312MSTL_CONSTEXPR20 void radix_sort(Iterator first, Iterator last, Mapper mapper = Mapper()) {
313 _MSTL radix_sort_less(first, last, mapper);
314}
315
316// smooth sort : Ot(NlogN) Om(1) unstable
317template <typename Iterator>
318MSTL_CONSTEXPR20 void smooth_sort(Iterator first, Iterator last) {
319 _MSTL make_leonardo_heap(first, last);
320 _MSTL sort_leonardo_heap(first, last);
321}
322
323// tim sort : Ot(NlogN) Om(N) stable
324template <typename Iterator, typename Compare, enable_if_t<
326MSTL_CONSTEXPR20 void tim_sort(Iterator first, Iterator last, Compare comp) {
327 constexpr int MIN_MERGE = 32;
329 for (Iterator i = first; i < last; i += MIN_MERGE) {
330 Iterator end = _MSTL min(i + MIN_MERGE, last);
331 _MSTL insertion_sort(i, end, comp);
332 }
333 for (int size = MIN_MERGE; size < n; size *= 2) {
334 for (Iterator left = first; left < last; left += 2 * size) {
335 Iterator mid = left + size;
336 Iterator right = _MSTL min(left + 2 * size, last);
337 if (mid < right) {
338 _MSTL inplace_merge(left, mid, right, comp);
339 }
340 }
341 }
342}
343
344template <typename Iterator>
345MSTL_CONSTEXPR20 void tim_sort(Iterator first, Iterator last) {
346 return _MSTL tim_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
347}
348
349// monkey sort : Ot-avg((N + 1)!) Om(1) unstable
350template <typename Iterator, typename Compare, enable_if_t<
352void monkey_sort(Iterator first, Iterator last, Compare comp) {
353 while (!_MSTL is_sorted(first, last, comp)) {
354 _MSTL shuffle(first, last);
355 }
356}
357
358template <typename Iterator>
359void monkey_sort(Iterator first, Iterator last) {
360 return _MSTL monkey_sort(first, last, _MSTL less<iter_value_t<Iterator>>());
361}
362
364#endif // MSTL_CORE_ALGORITHM_EXT_SORT_HPP__
constexpr Iterator max_element(Iterator first, Iterator last, Compare comp)
查找范围中的最大元素
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 iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
MSTL_INLINE17 constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
MSTL_INLINE17 constexpr bool is_ranges_fwd_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
获取迭代器的差值类型
constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
MSTL_NODISCARD constexpr reverse_iterator< Iterator > make_reverse_iterator(Iterator it) noexcept(is_nothrow_move_constructible_v< Iterator >)
创建反向迭代器
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_MSTL swap(*a, *b)))
交换迭代器指向的元素
constexpr void fill(Iterator first, Iterator last, const T &value)
填充范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制范围元素
constexpr Iterator2 transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op) noexcept(noexcept(++first) &&noexcept(++result) &&noexcept(*result=op(*first)))
对范围元素应用一元变换
void shuffle(Iterator first, Iterator last)
随机重排序列
void insertion_sort(Iterator first, Iterator last, Compare comp)
插入排序
bool is_sorted(Iterator first, Iterator last, Compare comp)
检查范围是否已排序
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
恒等仿函数
指针或迭代器行为异常
小于比较仿函数
存储两个值的元组对
T2 second
第二个元素
T1 first
第一个元素