12 #ifndef TLX_CONTAINER_D_ARY_HEAP_HEADER 13 #define TLX_CONTAINER_D_ARY_HEAP_HEADER 35 template <
typename KeyType,
unsigned Arity = 2,
36 typename Compare = std::less<KeyType> >
39 static_assert(Arity,
"Arity must be greater than zero.");
45 static constexpr
size_t arity = Arity;
57 : heap_(0), cmp_(cmp) { }
61 heap_.reserve(new_size);
78 size_t size() const noexcept {
return heap_.size(); }
81 size_t capacity() const noexcept {
return heap_.capacity(); }
84 bool empty() const noexcept {
return heap_.empty(); }
89 heap_.push_back(new_key);
96 heap_.push_back(std::move(new_key));
128 template <
class InputIterator>
130 heap_.assign(first, last);
136 heap_.resize(keys.size());
137 std::copy(keys.begin(), keys.end(), heap_.begin());
145 heap_ = std::move(keys);
155 std::queue<size_t> q;
159 size_t s = q.front();
162 for (
size_t i = 0; i < arity && l < heap_.size(); ++i) {
165 if (
cmp_(heap_[l], heap_[s]))
175 size_t left(
size_t k)
const {
return arity * k + 1; }
183 key_type value = std::move(heap_[k]);
185 while (k > 0 && !
cmp_(heap_[p], value)) {
186 heap_[k] = std::move(heap_[p]);
189 heap_[k] = std::move(value);
195 key_type value = std::move(heap_[k]);
198 if (l >= heap_.size()) {
204 while (++l < right) {
205 if (
cmp_(heap_[l], heap_[c])) {
212 if (!
cmp_(heap_[c], value)) {
217 heap_[k] = std::move(heap_[c]);
220 heap_[k] = std::move(value);
225 if (heap_.size() >= 2) {
227 size_t last_internal = (heap_.size() - 2) / arity;
228 for (
size_t i = last_internal + 1; i; --i) {
231 key_type value = std::move(heap_[cur]);
234 size_t l =
left(cur);
237 for (
size_t j = l + 1;
238 j - l < arity && j < heap_.size(); ++j) {
239 if (
cmp_(heap_[j], heap_[min_elem]))
245 if (
cmp_(heap_[min_elem], value)) {
246 heap_[cur] = std::move(heap_[min_elem]);
251 }
while (cur <= last_internal);
252 heap_[cur] = std::move(value);
259 template <
typename KeyType,
unsigned Arity = 2,
260 typename Compare = std::less<KeyType> >
267 #endif // !TLX_CONTAINER_D_ARY_HEAP_HEADER bool sanity_check()
For debugging: runs a BFS from the root node and verifies that the heap property is respected...
void pop()
Removes the top item.
compare_type cmp_
Compare function.
void push(const key_type &new_key)
Inserts a new item.
key_type extract_top()
Removes and returns the top item.
void sift_up(size_t k)
Pushes the node at position k up until either it becomes the root or its parent has lower or equal pr...
void update_all()
Rebuilds the heap.
void sift_down(size_t k)
Pushes the item at position k down until either it becomes a leaf or all its children have higher pri...
void clear()
Empties the heap.
This class implements a d-ary comparison-based heap usable as a priority queue.
static constexpr size_t arity
const key_type & top() const noexcept
Returns the top item.
static uint32_t min(uint32_t x, uint32_t y)
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
void reserve(size_t new_size)
Allocates space for new_size items.
std::vector< key_type > heap_
Cells in the heap.
bool empty() const noexcept
Returns true if the heap has no items, false otherwise.
DAryHeap(compare_type cmp=compare_type())
Allocates an empty heap.
size_t size() const noexcept
Returns the number of items in the heap.
void build_heap(const std::vector< key_type > &keys)
Builds a heap from the vector keys. Items of keys are copied.
void build_heap(InputIterator first, InputIterator last)
Builds a heap from a container.
DAryHeap & operator=(const DAryHeap &)=default
size_t parent(size_t k) const
Returns the position of the parent of the node at position k.
size_t capacity() const noexcept
Returns the capacity of the heap.
void build_heap(std::vector< key_type > &&keys)
Builds a heap from the vector keys. Items of keys are moved.
void push(key_type &&new_key)
Inserts a new item.
size_t left(size_t k) const
Returns the position of the left child of the node at position k.
void heapify()
Reorganize heap_ into a heap.