Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynArrayHeap.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31
53# ifndef TPL_DYNARRAYHEAP_H
54# define TPL_DYNARRAYHEAP_H
55
56# include <ah-concepts.H>
57# include <algorithm>
58# include <cstddef>
59# include <stdexcept>
60# include <utility>
61
62# include <tpl_dynArray.H>
63# include <ah-errors.H>
64
65namespace Aleph
66{
74 template <typename T, class Compare>
75 inline
76 size_t sift_up(DynArray<T> & a, const size_t l, const size_t r, Compare & cmp) noexcept
77 {
78 for (size_t p, i = r; i > l; i = p)
79 {
80 p = u_index(i); // parent index (p = i / 2)
81
82 // Prefetch grandparent for next iteration
83 if (const size_t gp = u_index(p); gp >= l)
84 __builtin_prefetch(&a.access(gp), 0, 1);
85
86 T & ap = a.access(p);
87 T & ai = a.access(i);
88 if (cmp(ap, ai)) [[likely]] // heap property holds
89 return i;
90
91 std::swap(ap, ai); // swap and continue at parent
92 }
93
94 return l;
95 }
96
102 template <typename T, class Compare>
103 inline
104 void sift_down(DynArray<T> & a, const size_t l, const size_t r, Compare & cmp) noexcept
105 {
106 size_t i = l;
107 while (true)
108 {
109 size_t c = l_index(i); // left child index (c = 2 * i)
110 if (c > r) [[unlikely]] // no left child
111 return;
112
113 // Prefetch grandchildren for next iteration
114 if (const size_t gc = l_index(c); gc <= r)
115 __builtin_prefetch(&a.access(gc), 0, 1);
116
117 T *ac = &a.access(c);
118 if (c + 1 <= r) // right child exists
119 {
120 T *ac1 = &a.access(c + 1);
121 if (cmp(*ac1, *ac)) // pick the child with higher priority
122 {
123 c++;
124 ac = ac1;
125 }
126 }
127
128 T & ai = a.access(i);
129 if (cmp(ai, *ac)) [[likely]] // heap property holds
130 return;
131
132 std::swap(*ac, ai);
133 i = c;
134 }
135 }
136
137
146 template <typename T, class Compare = Aleph::less<T>>
148 class DynArrayHeap : public LocateFunctions<DynArrayHeap<T, Compare>, T>,
149 public FunctionalMethods<DynArrayHeap<T, Compare>, T>,
150 public GenericKeys<DynArrayHeap<T, Compare>, T>,
151 public EqualToMethod<DynArrayHeap<T, Compare>>,
152 public StlAlephIterator<DynArrayHeap<T, Compare>>
153 {
155 size_t num_items = 0;
156
157 Compare cmp;
158
159 static size_t r_index(const size_t & i) noexcept
160 {
161 return (i << 1) + 1; // right child index
162 }
163
164 public:
165 using Item_Type = T;
166
168 DynArrayHeap(Compare cmp_fct = Compare()) : cmp(cmp_fct)
169 {
170 // empty
171 }
172
174
176
185 {
186 ah_underflow_error_if(num_items == 0) << "Heap is empty";
187
188 return array.access(1);
189 }
190
192 const T &top() const
193 {
194 ah_underflow_error_if(num_items == 0) << "Heap is empty";
195
196 return array.access(1);
197 }
198
207 T &insert(const T & key)
208 {
209 array.touch(++num_items) = key; // place new element
210 const size_t pos = sift_up(array, 1, num_items, cmp);
211 return array.access(pos);
212 }
213
219 T &insert(T && key)
220 {
221 array.touch(++num_items) = std::move(key); // place new element
222 const size_t pos = sift_up(array, 1, num_items, cmp);
223 return array.access(pos);
224 }
225
230 void reserve(size_t n)
231 {
232 ah_out_of_range_error_if(num_items > n) << "DynArrayHeap::reserve: n smaller than size";
233 array.reserve(n);
234 }
235
240 T &insert_direct(const T & key)
241 {
242 array(++num_items) = key; // place new element
243 const size_t pos = sift_up(array, 1, num_items, cmp);
244 return array.access(pos);
245 }
246
249 {
250 array(++num_items) = std::move(key); // place new element
251 const size_t pos = sift_up(array, 1, num_items, cmp);
252 return array.access(pos);
253 }
254
256 T &put(const T & key) { return insert(key); }
257
259 T &put(T && key) { return insert(std::move(key)); }
260
262 T &append(const T & key) { return insert(key); }
263
265 T &append(T && key) { return insert(std::move(key)); }
266
275 {
276 ah_underflow_error_if(num_items == 0) << "Heap is empty";
277
278 T & a1 = array(1);
279 T ret_val = std::move(a1);
280 if (num_items > 1)
281 {
282 a1 = std::move(array(num_items));
283 --num_items;
285 }
286 else
287 --num_items;
288
289 array.cut(num_items + 1);
290
291 return ret_val;
292 }
293
296 {
297 return getMin();
298 }
299
302 {
303 return getMin();
304 }
305
307 [[nodiscard]] constexpr size_t size() const noexcept { return num_items; }
308
310 [[nodiscard]] constexpr bool is_empty() const noexcept { return num_items == 0; }
311
312 struct Iterator : DynArray<T>::Iterator
313 {
314 using Base = typename DynArray<T>::Iterator;
315
317 {
318 if (h.num_items != 0)
319 this->next_ne();
320 }
321
322 Iterator() = default;
323
325 {
326 return this->curr_idx != 0 and this->curr_idx != this->array_ptr->size();
327 }
328
329 [[nodiscard]] long get_pos() const noexcept { return this->Base::get_pos() - 1; }
330 };
331
338 template <class Operation>
340 {
341 for (Iterator it(*this); it.has_curr(); it.next_ne())
342 if (not operation(it.get_curr()))
343 return false;
344 return true;
345 }
346
347 template <class Operation>
349 {
350 return const_cast<DynArrayHeap &>(*this).traverse<Operation>(operation);
351 }
352
353 template <class Operation>
355 {
357 }
358
359 template <class Operation>
361 {
363 }
364 };
365} // end namespace Aleph
366
367# endif // TPL_DYNARRAYHEAP_H
#define Args_Ctor(Name, Type)
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:373
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Definition ahDry.H:113
long double h
Definition btreepic.C:154
Dynamic heap (priority queue) backed by DynArray.
T & insert_direct(T &&key)
Move overload of insert_direct().
static size_t r_index(const size_t &i) noexcept
DynArrayHeap(Compare cmp_fct=Compare())
Default constructor.
T & put(T &&key)
Alias for insert() (move overload).
void reserve(size_t n)
Ensure the underlying array has capacity for at least n elements.
constexpr bool is_empty() const noexcept
Return true if the heap is empty.
T getMin()
Remove and return the top element.
bool traverse(Operation &operation)
Traverse all elements in the heap.
T & put(const T &key)
Alias for insert().
bool traverse(Operation &operation) const
T & append(const T &key)
Alias for insert().
bool traverse(Operation &&operation=Operation()) const
T & insert(const T &key)
Insert a copy of key into the heap.
bool traverse(Operation &&operation=Operation())
T & insert(T &&key)
Insert a key by moving it into the heap.
T & top()
Return the element with highest priority (the heap top).
T & insert_direct(const T &key)
Insert by directly indexing into the backing array.
const T & top() const
Const overload of top().
T & append(T &&key)
Alias for insert() (move overload).
constexpr size_t size() const noexcept
Return the number of elements.
Iterator on the items of array.
void next_ne() noexcept
Move the iterator one position forward guaranteeing no exception.
size_t size() const noexcept
Return the current dimension of array.
Equality test for containers.
Definition ah-dry.H:1959
Common methods to the Aleph-w ( ) containers.
Definition ah-dry.H:658
and
Conditional mapping of the elements of the container.
Definition ah-dry.H:1137
Common sequential searching methods on containers.
Definition ah-dry.H:200
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t l_index(const size_t i)
Map a binary heap index to the index of its left child.
Definition ahUtils.H:217
void sift_down(T *ptr, const size_t l, const size_t r, Compare &cmp)
Restore the heap property by moving the element at position l downwards.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
size_t u_index(const size_t &i)
Map a binary heap index to the index of its parent.
Definition ahUtils.H:203
T & sift_up(T *ptr, const size_t l, const size_t r, Compare &cmp)
Restore the heap property by moving the element at position r upwards.
typename DynArray< T >::Iterator Base
bool has_curr() const noexcept
Iterator(const DynArrayHeap &h) noexcept
long get_pos() const noexcept
Generic list of items stored in a container.
Definition ah-dry.H:1846
gsl_rng * r
Lazy and scalable dynamic array implementation.
DynList< int > l