12 #ifndef TLX_CONTAINER_D_ARY_ADDRESSABLE_INT_HEAP_HEADER 13 #define TLX_CONTAINER_D_ARY_ADDRESSABLE_INT_HEAP_HEADER 39 template <
typename KeyType,
unsigned Arity = 2,
40 class Compare = std::less<KeyType> >
43 static_assert(std::numeric_limits<KeyType>::is_integer &&
44 !std::numeric_limits<KeyType>::is_signed,
45 "KeyType must be an unsigned integer type.");
46 static_assert(Arity,
"Arity must be greater than zero.");
52 static constexpr
size_t arity = Arity;
72 : heap_(0), handles_(0), cmp_(cmp) { }
76 if (handles_.size() < new_size) {
78 heap_.reserve(new_size);
92 std::fill(handles_.begin(), handles_.end(),
not_present());
97 size_t size() const noexcept {
return heap_.size(); }
100 size_t capacity() const noexcept {
return heap_.capacity(); }
103 bool empty() const noexcept {
return heap_.empty(); }
109 if (new_key >= handles_.size()) {
117 handles_[new_key] =
static_cast<key_type>(heap_.size());
118 heap_.push_back(new_key);
126 if (new_key >= handles_.size()) {
134 handles_[new_key] =
static_cast<key_type>(heap_.size());
135 heap_.push_back(std::move(new_key));
144 handles_[heap_[h]] = h;
165 void pop() {
remove(heap_[0]); }
188 if (key >= handles_.size() || handles_[key] ==
not_present()) {
191 else if (handles_[key] &&
192 cmp_(heap_[handles_[key]], heap_[
parent(handles_[key])])) {
202 return key < handles_.size() ? handles_[key] !=
not_present() :
false;
206 template <
class InputIterator>
208 heap_.assign(first, last);
214 heap_.resize(keys.size());
215 std::copy(keys.begin(), keys.end(), heap_.begin());
223 heap_ = std::move(keys);
233 std::vector<unsigned char> mark(handles_.size());
234 std::queue<size_t> q;
238 mark.at(heap_[0]) = 1;
240 size_t s = q.front();
243 for (
size_t i = 0; i < arity && l < heap_.size(); ++i) {
246 if (
cmp_(heap_[l], heap_[s]))
249 if (handles_[heap_[l]] != l)
252 mark.at(heap_[l]) = 1;
257 for (
size_t i = 0; i < mark.size(); ++i) {
266 size_t left(
size_t k)
const {
return arity * k + 1; }
276 while (k > 0 && !
cmp_(heap_[p], value)) {
277 heap_[k] = std::move(heap_[p]);
278 handles_[heap_[k]] = k;
282 heap_[k] = std::move(value);
291 if (l >= heap_.size()) {
297 while (++l < right) {
298 if (
cmp_(heap_[l], heap_[c])) {
305 if (!
cmp_(heap_[c], value)) {
310 heap_[k] = std::move(heap_[c]);
311 handles_[heap_[k]] = k;
315 heap_[k] = std::move(value);
320 key_type max_key = heap_.empty() ? 0 : heap_.front();
321 if (heap_.size() >= 2) {
323 size_t last_internal = (heap_.size() - 2) / arity;
324 for (
size_t i = last_internal + 1; i; --i) {
331 size_t l =
left(cur);
332 max_key =
std::max(max_key, heap_[l]);
335 for (
size_t j = l + 1;
336 j - l < arity && j < heap_.size(); ++j) {
337 if (
cmp_(heap_[j], heap_[min_elem]))
339 max_key =
std::max(max_key, heap_[j]);
344 if (
cmp_(heap_[min_elem], value)) {
345 heap_[cur] = std::move(heap_[min_elem]);
350 }
while (cur <= last_internal);
351 heap_[cur] = std::move(value);
355 handles_.resize(
std::max(handles_.size(),
static_cast<size_t>(max_key) + 1),
not_present());
356 for (
size_t i = 0; i < heap_.size(); ++i)
357 handles_[heap_[i]] = i;
362 template <
typename KeyType,
unsigned Arity = 2,
363 typename Compare = std::less<KeyType> >
371 #endif // !TLX_CONTAINER_D_ARY_ADDRESSABLE_INT_HEAP_HEADER static constexpr size_t arity
void build_heap(std::vector< key_type > &&keys)
Builds a heap from the vector keys. Items of keys are moved.
void heapify()
Reorganize heap_ into a heap.
static uint_pair max()
return an uint_pair instance containing the largest value possible
bool empty() const noexcept
Returns true if the heap has no items, false otherwise.
DAryAddressableIntHeap & operator=(const DAryAddressableIntHeap &)=default
This class implements an addressable integer priority queue, precisely a d-ary heap.
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 push(const key_type &new_key)
Inserts a new item.
void build_heap(InputIterator first, InputIterator last)
Builds a heap from a container.
key_type extract_top()
Removes and returns the top item.
void reserve(size_t new_size)
Allocates space for new_size items.
void pop()
Removes the top item.
DAryAddressableIntHeap(compare_type cmp=compare_type())
Allocates an empty heap.
void clear()
Empties the heap.
std::vector< key_type > heap_
Cells 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 swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
void update_all()
Rebuilds the heap.
compare_type cmp_
Compare function.
void push(key_type &&new_key)
Inserts a new item.
size_t size() const noexcept
Returns the number of items in the heap.
void update(key_type key)
Updates the priority queue after the priority associated to the item with key key has been changed; i...
size_t left(size_t k) const
Returns the position of the left child of the node at position k.
static uint_pair min()
return an uint_pair instance containing the smallest value possible
bool contains(key_type key) const
Returns true if the key key is in the heap, false otherwise.
static constexpr key_type not_present()
Marks a key that is not in the heap.
const key_type & top() const noexcept
Returns the top item.
std::vector< key_type > handles_
Positions of the keys in the heap vector.