MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
leonardo_heap.hpp
1#ifndef MSTL_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
2#define MSTL_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
3#include "../container/vector.hpp"
4#include "../numeric/math.hpp"
6
7template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
8void adjust_leonardo_heap(Iterator first, size_t current_heap, int level_index, vector<int>& levels) {
9 size_t child_heap1;
10 size_t child_heap2;
11 while (level_index > 0) {
12 size_t prev_heap = current_heap - leonardo(levels[level_index]);
13 if (*(first + current_heap) < *(first + prev_heap)) {
14 if (levels[level_index] > 1) {
15 child_heap1 = current_heap - 1 - leonardo(levels[level_index] - 2);
16 child_heap2 = current_heap - 1;
17 if (*(first + prev_heap) < *(first + child_heap1)) break;
18 if (*(first + prev_heap) < *(first + child_heap2)) break;
19 }
20 _MSTL iter_swap(first + current_heap, first + prev_heap);
21 current_heap = prev_heap;
22 --level_index;
23 }
24 else {
25 break;
26 }
27 }
28 int current_level = levels[level_index];
29 while (current_level > 1) {
30 size_t max_child = current_heap;
31 child_heap1 = current_heap - 1 - leonardo(current_level - 2);
32 child_heap2 = current_heap - 1;
33
34 if (*(first + max_child) < *(first + child_heap1)) max_child = child_heap1;
35 if (*(first + max_child) < *(first + child_heap2)) max_child = child_heap2;
36
37 if (max_child == child_heap1) {
38 _MSTL iter_swap(first + current_heap, first + child_heap1);
39 current_heap = child_heap1;
40 --current_level;
41 }
42 else if (max_child == child_heap2) {
43 _MSTL iter_swap(first + current_heap, first + child_heap2);
44 current_heap = child_heap2;
45 current_level -= 2;
46 }
47 else {
48 break;
49 }
50 }
51}
52
53template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
54void push_leonardo_heap(Iterator first, Iterator last) {
55 if (first == last) return;
56 const size_t size = _MSTL distance(first, last);
57 vector<int> levels = { 1 };
58 int toplevel = 0;
59 for (size_t i = 1; i < size - 1; ++i) {
60 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
61 --toplevel;
62 ++levels[toplevel];
63 }
64 else if (levels[toplevel] != 1) {
65 ++toplevel;
66 levels.push_back(1);
67 }
68 else {
69 ++toplevel;
70 levels.push_back(0);
71 }
72 }
73 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
74 --toplevel;
75 ++levels[toplevel];
76 }
77 else if (levels[toplevel] != 1) {
78 ++toplevel;
79 levels.push_back(1);
80 }
81 else {
82 ++toplevel;
83 levels.push_back(0);
84 }
85 _MSTL adjust_leonardo_heap(first, size - 1, toplevel, levels);
86}
87
88template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
89void pop_leonardo_heap(Iterator first, Iterator last) {
90 if (first == last) return;
91 const size_t size = _MSTL distance(first, last);
92 vector<int> levels = { 1 };
93 int toplevel = 0;
94 for (size_t i = 1; i < size; ++i) {
95 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
96 --toplevel;
97 ++levels[toplevel];
98 }
99 else if (levels[toplevel] != 1) {
100 ++toplevel;
101 levels.push_back(1);
102 }
103 else {
104 ++toplevel;
105 levels.push_back(0);
106 }
107 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
108 }
109 if (levels[toplevel] <= 1) {
110 --toplevel;
111 }
112 else {
113 --levels[toplevel];
114 levels.push_back(levels[toplevel] - 1);
115 ++toplevel;
116 _MSTL adjust_leonardo_heap(first, size - 2 - leonardo(levels[toplevel]), toplevel - 1, levels);
117 _MSTL adjust_leonardo_heap(first, size - 2, toplevel, levels);
118 }
119}
120
121template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
122void sort_leonardo_heap(Iterator first, Iterator last) {
123 if (first == last) return;
124 const size_t size = _MSTL distance(first, last);
125 vector<int> levels = { 1 };
126 int toplevel = 0;
127 for (size_t i = 1; i < size; ++i) {
128 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
129 --toplevel;
130 ++levels[toplevel];
131 }
132 else if (levels[toplevel] != 1) {
133 ++toplevel;
134 levels.push_back(1);
135 }
136 else {
137 ++toplevel;
138 levels.push_back(0);
139 }
140 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
141 }
142 for (size_t i = size - 2; i > 0; --i) {
143 if (levels[toplevel] <= 1) {
144 --toplevel;
145 }
146 else {
147 --levels[toplevel];
148 levels.push_back(levels[toplevel] - 1);
149 ++toplevel;
150
151 _MSTL adjust_leonardo_heap(first, i - leonardo(levels[toplevel]), toplevel - 1, levels);
152 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
153 }
154 }
155}
156
157template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
158void make_leonardo_heap(Iterator first, Iterator last) {
159 if (first == last) return;
160 const size_t size = _MSTL distance(first, last);
161 vector<int> levels = { 1 };
162 int toplevel = 0;
163
164 for (size_t i = 1; i < size; ++i) {
165 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
166 --toplevel;
167 ++levels[toplevel];
168 }
169 else if (levels[toplevel] != 1) {
170 ++toplevel;
171 levels.push_back(1);
172 }
173 else {
174 ++toplevel;
175 levels.push_back(0);
176 }
177 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
178 }
179}
180
182#endif // MSTL_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 uint64_t leonardo(const uint32_t n)
计算莱昂纳多数
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_MSTL swap(*a, *b)))
交换迭代器指向的元素
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
MSTL数学函数库