NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
leonardo_heap.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
2#define NEFORCE_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
3
11
14NEFORCE_BEGIN_NAMESPACE__
15
21
115
127template <typename Iterator>
128void adjust_leonardo_heap(Iterator first, size_t current_heap, int level_index, vector<int>& levels) {
129 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
130
131 size_t child_heap1 = 0;
132 size_t child_heap2 = 0;
133 while (level_index > 0) {
134 size_t prev_heap = current_heap - leonardo(levels[level_index]);
135 if (*(first + current_heap) < *(first + prev_heap)) {
136 if (levels[level_index] > 1) {
137 child_heap1 = current_heap - 1 - leonardo(levels[level_index] - 2);
138 child_heap2 = current_heap - 1;
139 if (*(first + prev_heap) < *(first + child_heap1)) {
140 break;
141 }
142 if (*(first + prev_heap) < *(first + child_heap2)) {
143 break;
144 }
145 }
146 _NEFORCE iter_swap(first + current_heap, first + prev_heap);
147 current_heap = prev_heap;
148 --level_index;
149 } else {
150 break;
151 }
152 }
153 int current_level = levels[level_index];
154 while (current_level > 1) {
155 size_t max_child = current_heap;
156 child_heap1 = current_heap - 1 - leonardo(current_level - 2);
157 child_heap2 = current_heap - 1;
158
159 if (*(first + max_child) < *(first + child_heap1)) {
160 max_child = child_heap1;
161 }
162 if (*(first + max_child) < *(first + child_heap2)) {
163 max_child = child_heap2;
164 }
165
166 if (max_child == child_heap1) {
167 _NEFORCE iter_swap(first + current_heap, first + child_heap1);
168 current_heap = child_heap1;
169 --current_level;
170 } else if (max_child == child_heap2) {
171 _NEFORCE iter_swap(first + current_heap, first + child_heap2);
172 current_heap = child_heap2;
173 current_level -= 2;
174 } else {
175 break;
176 }
177 }
178}
179
188template <typename Iterator>
189void push_leonardo_heap(Iterator first, Iterator last) {
190 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
191
192 if (first == last) {
193 return;
194 }
195 const size_t size = _NEFORCE distance(first, last);
196 if (size < 2) {
197 return;
198 }
199
200 vector<int> levels = {1};
201 int toplevel = 0;
202 for (size_t i = 1; i < size - 1; ++i) {
203 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
204 --toplevel;
205 ++levels[toplevel];
206 } else if (levels[toplevel] != 1) {
207 ++toplevel;
208 levels.push_back(1);
209 } else {
210 ++toplevel;
211 levels.push_back(0);
212 }
213 }
214 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
215 --toplevel;
216 ++levels[toplevel];
217 } else if (levels[toplevel] != 1) {
218 ++toplevel;
219 levels.push_back(1);
220 } else {
221 ++toplevel;
222 levels.push_back(0);
223 }
224 _NEFORCE adjust_leonardo_heap(first, size - 1, toplevel, levels);
225}
226
235template <typename Iterator>
236void pop_leonardo_heap(Iterator first, Iterator last) {
237 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
238
239 if (first == last) {
240 return;
241 }
242 const size_t size = _NEFORCE distance(first, last);
243 vector<int> levels = {1};
244 int toplevel = 0;
245 for (size_t i = 1; i < size; ++i) {
246 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
247 --toplevel;
248 ++levels[toplevel];
249 } else if (levels[toplevel] != 1) {
250 ++toplevel;
251 levels.push_back(1);
252 } else {
253 ++toplevel;
254 levels.push_back(0);
255 }
256 _NEFORCE adjust_leonardo_heap(first, i, toplevel, levels);
257 }
258 if (levels[toplevel] <= 1) {
259 --toplevel;
260 } else {
261 --levels[toplevel];
262 levels.push_back(levels[toplevel] - 1);
263 ++toplevel;
264 _NEFORCE adjust_leonardo_heap(first, size - 2 - leonardo(levels[toplevel]), toplevel - 1, levels);
265 _NEFORCE adjust_leonardo_heap(first, size - 2, toplevel, levels);
266 }
267}
268
277template <typename Iterator>
278void sort_leonardo_heap(Iterator first, Iterator last) {
279 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
280
281 if (first == last) {
282 return;
283 }
284 const size_t size = _NEFORCE distance(first, last);
285 if (size < 2) {
286 return;
287 }
288
289 vector<int> levels = {1};
290 int toplevel = 0;
291 for (size_t i = 1; i < size; ++i) {
292 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
293 --toplevel;
294 ++levels[toplevel];
295 } else if (levels[toplevel] != 1) {
296 ++toplevel;
297 levels.push_back(1);
298 } else {
299 ++toplevel;
300 levels.push_back(0);
301 }
302 _NEFORCE adjust_leonardo_heap(first, i, toplevel, levels);
303 }
304 for (size_t i = size - 2; i > 0; --i) {
305 if (levels[toplevel] <= 1) {
306 --toplevel;
307 } else {
308 --levels[toplevel];
309 levels.push_back(levels[toplevel] - 1);
310 ++toplevel;
311
312 _NEFORCE adjust_leonardo_heap(first, i - leonardo(levels[toplevel]), toplevel - 1, levels);
313 _NEFORCE adjust_leonardo_heap(first, i, toplevel, levels);
314 }
315 }
316}
317
326template <typename Iterator>
327void make_leonardo_heap(Iterator first, Iterator last) {
328 static_assert(is_ranges_rnd_iter_v<Iterator>, "Iterator must be random_access_iterator");
329
330 if (first == last) {
331 return;
332 }
333 const size_t size = _NEFORCE distance(first, last);
334 vector<int> levels = {1};
335 int toplevel = 0;
336
337 for (size_t i = 1; i < size; ++i) {
338 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
339 --toplevel;
340 ++levels[toplevel];
341 } else if (levels[toplevel] != 1) {
342 ++toplevel;
343 levels.push_back(1);
344 } else {
345 ++toplevel;
346 levels.push_back(0);
347 }
348 _NEFORCE adjust_leonardo_heap(first, i, toplevel, levels);
349 }
350}
351 // LeonardoHeap
353
358
372template <typename Iterator>
373NEFORCE_CONSTEXPR20 void smooth_sort(Iterator first, Iterator last) {
374 _NEFORCE make_leonardo_heap(first, last);
375 _NEFORCE sort_leonardo_heap(first, last);
376}
377 // SortAlgorithms
379 // StandardAlgorithms
381
382NEFORCE_END_NAMESPACE__
383#endif // NEFORCE_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
动态大小数组容器
constexpr void push_back(const T &value)
在末尾拷贝插入元素
constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
void pop_leonardo_heap(Iterator first, Iterator last)
从莱昂纳多堆中弹出最大元素
void sort_leonardo_heap(Iterator first, Iterator last)
使用莱昂纳多堆进行排序
void push_leonardo_heap(Iterator first, Iterator last)
向莱昂纳多堆中推入元素
void adjust_leonardo_heap(Iterator first, size_t current_heap, int level_index, vector< int > &levels)
调整莱昂纳多堆
void make_leonardo_heap(Iterator first, Iterator last)
构建莱昂纳多堆
constexpr uint64_t leonardo(const uint32_t n) noexcept
计算莱昂纳多数
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
constexpr void smooth_sort(Iterator first, Iterator last)
平滑排序
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
数学函数库
动态大小数组容器