qxLib
sort.h
Go to the documentation of this file.
1 /**
2 
3  @file sort.h
4  @author Khrapov
5  @date 1.03.2020
6  @copyright © Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 #pragma once
10 
11 #include <qx/typedefs.h>
12 
13 #include <qx/meta/type_traits.h>
14 #include <algorithm>
15 #include <functional>
16 #include <vector>
17 
18 namespace qx
19 {
20 
21 constexpr size_t SORT_COUNTING_MAX_BUFFER_SIZE = 100000;
22 
23 //!< vector of iterator value
24 template<class it_t>
25 using vector_of_values = std::vector<iterator_value_t<it_t>>;
26 
27 /**
28  @brief Check if sort really needed
29  @complexity O(1)
30  @tparam random_it_t - random access iterator
31  @param begin - begin iterator
32  @param end - end iterator
33  @retval - false if [begin, end) already sorted
34 **/
35 template<class random_it_t>
36 inline bool sort_required(random_it_t begin, random_it_t end);
37 
38 /**
39  @brief Insertion sort
40  @details Stable
41  @complexity O(N^2)
42  @tparam random_it_t - random access iterator
43  @tparam compare_t - function object type satisfying binary predicate requirements
44  @param begin - begin iterator
45  @param end - end iterator
46  @param compare - comparison function
47 **/
48 template<class random_it_t, class compare_t = std::less<>>
49 inline void sort_insertion(random_it_t begin, random_it_t end, compare_t compare = compare_t());
50 
51 /**
52  @brief Insertion sort
53  @details Stable
54  @complexity O(N^2)
55  @tparam container_t - container type
56  @tparam compare_t - function object type satisfying binary predicate requirements
57  @param cont - container ref
58  @param compare - comparison function
59 **/
60 template<class container_t, class compare_t = std::less<>>
61 inline void sort_insertion(container_t& cont, compare_t compare = compare_t());
62 
63 /**
64  @brief Selection sort
65  @details Unstable
66  @complexity O(N^2)
67  @tparam random_it_t - random access iterator
68  @tparam compare_t - function object type satisfying binary predicate requirements
69  @param begin - begin iterator
70  @param end - end iterator
71  @param compare - comparison function
72 **/
73 template<class random_it_t, class compare_t = std::less<>>
74 inline void sort_selection(random_it_t begin, random_it_t end, compare_t compare = compare_t());
75 
76 /**
77  @brief Selection sort
78  @details Unstable
79  @complexity O(N^2)
80  @tparam container_t - container type
81  @tparam compare_t - function object type satisfying binary predicate requirements
82  @param cont - container ref
83  @param compare - comparison function
84 **/
85 template<class container_t, class compare_t = std::less<>>
86 inline void sort_selection(container_t& cont, compare_t compare = compare_t());
87 
88 /**
89  @brief Bubble sort
90  @details Stable
91  @complexity O(N^2)
92  @tparam random_it_t - random access iterator
93  @tparam compare_t - function object type satisfying binary predicate requirements
94  @param begin - begin iterator
95  @param end - end iterator
96  @param compare - comparison function
97 **/
98 template<class random_it_t, class compare_t = std::less<>>
99 inline void sort_bubble(random_it_t begin, random_it_t end, compare_t compare = compare_t());
100 
101 /**
102  @brief Bubble sort
103  @details Stable
104  @complexity O(N^2)
105  @tparam container_t - container type
106  @tparam compare_t - function object type satisfying binary predicate requirements
107  @param cont - container ref
108  @param compare - comparison function
109 **/
110 template<class container_t, class compare_t = std::less<>>
111 inline void sort_bubble(container_t& cont, compare_t compare = compare_t());
112 
113 /**
114  @brief Adjust heap
115  @complexity O(log(N))
116  @tparam random_it_t - random access iterator
117  @tparam compare_t - function object type satisfying binary predicate requirements
118  @param begin - whole heap root random_it_type
119  @param nHeapSize - whole heap size for out of range check
120  @param nPosition - current root nPosition
121  @param compare - comparison function
122 **/
123 template<class random_it_t, class compare_t>
124 inline void adjust_heap(random_it_t begin, size_t nHeapSize, size_t nPosition, compare_t compare = compare_t());
125 
126 /**
127  @brief Make heap at range
128  @tparam random_it_t - random access iterator
129  @tparam compare_t - function object type satisfying binary predicate requirements
130  @param begin - begin iterator
131  @param end - end iterator
132  @param compare - comparison function
133 **/
134 template<class random_it_t, class compare_t>
135 inline void make_heap(random_it_t begin, random_it_t end, compare_t compare = compare_t());
136 
137 /**
138  @brief Heap sort
139  @details Unstable
140  @complexity O(Nlog(N))
141  @tparam random_it_t - random access iterator
142  @tparam compare_t - function object type satisfying binary predicate requirements
143  @param begin - begin iterator
144  @param end - end iterator
145  @param compare - comparison function
146 **/
147 template<class random_it_t, class compare_t = std::less<>>
148 inline void sort_heap(random_it_t begin, random_it_t end, compare_t compare = compare_t());
149 
150 /**
151  @brief Heap sort
152  @details Unstable
153  @complexity O(Nlog(N))
154  @tparam container_t - container type
155  @tparam compare_t - function object type satisfying binary predicate requirements
156  @param cont - container ref
157  @param compare - comparison function
158 **/
159 template<class container_t, class compare_t = std::less<>>
160 inline void sort_heap(container_t& cont, compare_t compare = compare_t());
161 
162 /**
163  @brief Quick sort based on Hoare partitioning
164  @details Unstable
165  @complexity O(Nlog(N))
166  @tparam random_it_t - random access iterator
167  @tparam compare_t - function object type satisfying binary predicate requirements
168  @param begin - begin iterator
169  @param end - end iterator
170  @param compare - comparison function
171 **/
172 template<class random_it_t, class compare_t = std::less<>>
173 inline void sort_quick_hoare(random_it_t begin, random_it_t end, compare_t compare = compare_t());
174 
175 /**
176  @brief Quick sort based on Hoare partitioning
177  @details Unstable
178  @complexity O(Nlog(N))
179  @tparam container_t - container type
180  @tparam compare_t - function object type satisfying binary predicate requirements
181  @param cont - container ref
182  @param compare - comparison function
183 **/
184 template<class container_t, class compare_t = std::less<>>
185 inline void sort_quick_hoare(container_t& cont, compare_t compare = compare_t());
186 
187 /**
188  @brief Quick sort based on three-way partitioning
189  @details Unstable
190  @complexity O(Nlog(N))
191  @tparam random_it_t - random access iterator
192  @tparam compare_t - function object type satisfying binary predicate requirements
193  @param begin - begin iterator
194  @param end - end iterator
195  @param compare - comparison function
196 **/
197 template<class random_it_t, class compare_t = std::less<>>
198 inline void sort_quick_three_way(random_it_t begin, random_it_t end, compare_t compare = compare_t());
199 
200 /**
201  @brief Quick sort based on three-way partitioning
202  @details Unstable
203  @complexity O(Nlog(N))
204  @tparam container_t - container type
205  @tparam compare_t - function object type satisfying binary predicate requirements
206  @param cont - container ref
207  @param compare - comparison function
208 **/
209 template<class container_t, class compare_t = std::less<>>
210 inline void sort_quick_three_way(container_t& cont, compare_t compare = compare_t());
211 
212 /**
213  @brief Quick sort based on dual-pivot partitioning
214  @details Unstable
215  @complexity O(Nlog(N))
216  @tparam random_it_t - random access iterator
217  @tparam compare_t - function object type satisfying binary predicate requirements
218  @param begin - begin iterator
219  @param end - end iterator
220  @param compare - comparison function
221 **/
222 template<class random_it_t, class compare_t = std::less<>>
223 inline void sort_quick_dual_pivot(random_it_t begin, random_it_t end, compare_t compare = compare_t());
224 
225 /**
226  @brief Quick sort based on dual-pivot partitioning
227  @details Unstable
228  @complexity O(Nlog(N))
229  @tparam container_t - container type
230  @tparam compare_t - function object type satisfying binary predicate requirements
231  @param cont - container ref
232  @param compare - comparison function
233 **/
234 template<class container_t, class compare_t = std::less<>>
235 inline void sort_quick_dual_pivot(container_t& cont, compare_t compare = compare_t());
236 
237 /**
238  @brief Merge with temp vector
239  @complexity O(N), O(N) memory
240  @tparam random_it_t - random access iterator
241  @tparam compare_t - function object type satisfying binary predicate requirements
242  @param begin - begin iterator
243  @param end - end iterator
244  @param compare - comparison function
245  @param pPreallocatedBuffer - preallocated buffer. default value will allocate a new one
246 **/
247 template<class random_it_t, class compare_t = std::less<>>
248 inline void merge(
249  random_it_t begin,
250  random_it_t end,
251  compare_t compare = compare_t(),
252  vector_of_values<random_it_t>* pPreallocatedBuffer = nullptr);
253 
254 /**
255  @brief Merge sort based on merge with temp vector
256  @details Stable
257  @complexity O(Nlog(N)), O(N) memory
258  @tparam random_it_t - random access iterator
259  @tparam compare_t - function object type satisfying binary predicate requirements
260  @param begin - begin iterator
261  @param end - end iterator
262  @param pPreallocatedBuffer - preallocated buffer. default value will allocate a new one
263  @param compare - comparison function
264 **/
265 template<class random_it_t, class compare_t = std::less<>>
266 inline void sort_merge(
267  random_it_t begin,
268  random_it_t end,
269  compare_t compare = compare_t(),
270  vector_of_values<random_it_t>* pPreallocatedBuffer = nullptr);
271 
272 /**
273  @brief Merge sort based on merge with temp vector
274  @details Stable
275  @complexity O(Nlog(N)), O(N) memory
276  @tparam container_t - container type
277  @tparam compare_t - function object type satisfying binary predicate requirements
278  @param cont - container ref
279  @param compare - comparison function
280  @param pPreallocatedBuffer - preallocated buffer. default value will allocate a new one
281 **/
282 template<class container_t, class compare_t = std::less<>>
283 inline void sort_merge(
284  container_t& cont,
285  compare_t compare = compare_t(),
286  vector_of_values<typename container_t::iterator>* pPreallocatedBuffer = nullptr);
287 
288 /**
289  @brief Counting sort for integral values
290  @complexity O(M + 2 * N), O(M) memory, where M = max - min + 1
291  @tparam random_it_t - random access iterator
292  @tparam compare_t - function object type satisfying binary predicate requirements
293  @param begin - begin iterator
294  @param end - end iterator
295  @param compare - comparison function
296  @param nMaxBufferSize - max buffer size. if required size is bigger than this value, sorting will fail
297  @retval - true if sorted, false if required buffer size is greather then max
298 **/
299 template<class random_it_t, class compare_t = std::less<>>
300 [[nodiscard]] inline bool sort_counting(
301  random_it_t begin,
302  random_it_t end,
303  compare_t compare = compare_t(),
304  size_t nMaxBufferSize = SORT_COUNTING_MAX_BUFFER_SIZE);
305 
306 /**
307  @brief Counting sort for integral values
308  @complexity O(M + 2 * N), O(M) memory, where M = max - min + 1
309  @tparam container_t - container type
310  @tparam compare_t - function object type satisfying binary predicate requirements
311  @param cont - container ref
312  @param compare - comparison function
313  @param nMaxBufferSize - max buffer size. if required size is bigger than this value, sorting will fail
314  @retval - true if sorted, false if required buffer size is greather then max
315 **/
316 template<class container_t, class compare_t = std::less<>>
317 [[nodiscard]] inline bool sort_counting(
318  container_t& cont,
319  compare_t compare = compare_t(),
320  size_t nMaxBufferSize = SORT_COUNTING_MAX_BUFFER_SIZE);
321 
322 /**
323  @brief Sort by the most suitable algorithm
324  @tparam random_it_t - random access iterator
325  @tparam compare_t - function object type satisfying binary predicate requirements
326  @param begin - begin iterator
327  @param end - end iterator
328  @param compare - comparison function
329 **/
330 template<class random_it_t, class compare_t = std::less<>>
331 inline void sort(random_it_t begin, random_it_t end, compare_t compare = compare_t());
332 
333 /**
334  @brief Sort by the most suitable algorithm
335  @tparam container_t - container type
336  @tparam compare_t - function object type satisfying binary predicate requirements
337  @param cont - container ref
338  @param compare - comparison function
339 **/
340 template<class container_t, class compare_t = std::less<>>
341 inline void sort(container_t& cont, compare_t compare = compare_t());
342 
343 } // namespace qx
344 
345 #include <qx/algo/sort.inl>
void sort_selection(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Selection sort.
Definition: sort.inl:40
void sort_quick_three_way(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Quick sort based on three-way partitioning.
Definition: sort.inl:194
void sort_insertion(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Insertion sort.
Definition: sort.inl:23
void sort_heap(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Heap sort.
Definition: sort.inl:135
void sort_bubble(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Bubble sort.
Definition: sort.inl:63
void sort(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Sort by the most suitable algorithm.
Definition: sort.inl:522
bool sort_counting(random_it_t begin, random_it_t end, compare_t compare=compare_t(), size_t nMaxBufferSize=SORT_COUNTING_MAX_BUFFER_SIZE)
Counting sort for integral values.
Definition: sort.inl:477
void adjust_heap(random_it_t begin, size_t nHeapSize, size_t nPosition, compare_t compare=compare_t())
Adjust heap.
Definition: sort.inl:90
bool sort_required(random_it_t begin, random_it_t end)
Check if sort really needed.
Definition: sort.inl:14
void sort_quick_hoare(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Quick sort based on Hoare partitioning.
Definition: sort.inl:158
void make_heap(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Make heap at range.
Definition: sort.inl:121
constexpr size_t SORT_COUNTING_MAX_BUFFER_SIZE
vector of iterator value
Definition: sort.h:21
void merge(random_it_t begin, random_it_t end, compare_t compare=compare_t(), vector_of_values< random_it_t > *pPreallocatedBuffer=nullptr)
Merge with temp vector.
Definition: sort.inl:386
void sort_quick_dual_pivot(random_it_t begin, random_it_t end, compare_t compare=compare_t())
Quick sort based on dual-pivot partitioning.
Definition: sort.inl:278
void sort_merge(random_it_t begin, random_it_t end, compare_t compare=compare_t(), vector_of_values< random_it_t > *pPreallocatedBuffer=nullptr)
Merge sort based on merge with temp vector.
Definition: sort.inl:441