1#ifndef MSTL_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
2#define MSTL_CORE_ALGORITHM_LEONARDO_HEAP_HPP__
3#include "../container/vector.hpp"
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) {
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;
21 current_heap = prev_heap;
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;
34 if (*(first + max_child) < *(first + child_heap1)) max_child = child_heap1;
35 if (*(first + max_child) < *(first + child_heap2)) max_child = child_heap2;
37 if (max_child == child_heap1) {
39 current_heap = child_heap1;
42 else if (max_child == child_heap2) {
44 current_heap = child_heap2;
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;
57 vector<int> levels = { 1 };
59 for (
size_t i = 1; i <
size - 1; ++i) {
60 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
64 else if (levels[toplevel] != 1) {
73 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
77 else if (levels[toplevel] != 1) {
85 _MSTL adjust_leonardo_heap(first,
size - 1, toplevel, levels);
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;
92 vector<int> levels = { 1 };
94 for (
size_t i = 1; i <
size; ++i) {
95 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
99 else if (levels[toplevel] != 1) {
107 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
109 if (levels[toplevel] <= 1) {
114 levels.push_back(levels[toplevel] - 1);
116 _MSTL adjust_leonardo_heap(first,
size - 2 -
leonardo(levels[toplevel]), toplevel - 1, levels);
117 _MSTL adjust_leonardo_heap(first,
size - 2, toplevel, levels);
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;
125 vector<int> levels = { 1 };
127 for (
size_t i = 1; i <
size; ++i) {
128 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
132 else if (levels[toplevel] != 1) {
140 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
142 for (
size_t i =
size - 2; i > 0; --i) {
143 if (levels[toplevel] <= 1) {
148 levels.push_back(levels[toplevel] - 1);
151 _MSTL adjust_leonardo_heap(first, i -
leonardo(levels[toplevel]), toplevel - 1, levels);
152 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
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;
161 vector<int> levels = { 1 };
164 for (
size_t i = 1; i <
size; ++i) {
165 if (toplevel > 0 && levels[toplevel - 1] - levels[toplevel] == 1) {
169 else if (levels[toplevel] != 1) {
177 _MSTL adjust_leonardo_heap(first, i, toplevel, levels);
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()))
获取容器的大小