aGrUM 3.0.0
a C++ library for (probabilistic) graphical models
heap_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
50#include <sstream>
51#include <string>
52
53// to ease IDE parser
55
56namespace gum {
57
58 // basic constructor. Creates an empty heap
59 template < typename Val, typename Cmp >
61 _heap_.reserve(capacity);
62
63 GUM_CONSTRUCTOR(Heap);
64 }
65
66 // initializer list constructor
67 template < typename Val, typename Cmp >
68 Heap< Val, Cmp >::Heap(std::initializer_list< Val > list) {
69 _heap_.reserve(list.size());
70 for (const auto& elt: list) {
71 insert(elt);
72 }
73
74 GUM_CONSTRUCTOR(Heap);
75 }
76
77 // copy constructor
78 template < typename Val, typename Cmp >
81 // for debugging purposes
82 GUM_CONS_CPY(Heap);
83 }
84
85 // move constructor
86 template < typename Val, typename Cmp >
88 _heap_(std::move(from._heap_)), _nb_elements_(std::move(from._nb_elements_)),
89 _cmp_(std::move(from._cmp_)) {
90 // for debugging purposes
91 GUM_CONS_MOV(Heap);
92 }
93
94 // destructor
95 template < typename Val, typename Cmp >
97 // for debugging purposes
98 GUM_DESTRUCTOR(Heap);
99 }
100
101 // copy operator
102 template < typename Val, typename Cmp >
104 // avoid self assignment
105 if (this != &from) {
106 try {
107 _heap_ = from._heap_;
108 } catch (...) {
109 _heap_.clear();
110 _nb_elements_ = 0;
111
112 throw;
113 }
114
115 // set the comparison function
116 _cmp_ = from._cmp_;
118
119 // for debugging purposes
120 GUM_OP_CPY(Heap);
121 }
122
123 return *this;
124 }
125
126 // move operator
127 template < typename Val, typename Cmp >
129 // avoid self assignment
130 if (this != &from) {
131 _heap_ = std::move(from._heap_);
132 _nb_elements_ = std::move(from._nb_elements_);
133 _cmp_ = std::move(from._cmp_);
134 }
135
136 return *this;
137 }
138
139 // returns the element at the top of the heap
140 template < typename Val, typename Cmp >
141 const Val& Heap< Val, Cmp >::top() const {
142 if (!_nb_elements_) { GUM_ERROR(NotFound, "empty heap") }
143
144 return _heap_[0];
145 }
146
147 // returns the number of elements in the heap
148 template < typename Val, typename Cmp >
149 Size Heap< Val, Cmp >::size() const noexcept {
150 return _nb_elements_;
151 }
152
153 // return the size of the array storing the heap
154 template < typename Val, typename Cmp >
156 return Size(_heap_.size());
157 }
158
159 // changes the size of the array storing the heap
160 template < typename Val, typename Cmp >
162 if (new_size > _nb_elements_) _heap_.reserve(new_size);
163 }
164
165 // removes the element at position 'index' from the heap
166 template < typename Val, typename Cmp >
168 if (index >= _nb_elements_) return;
169
170 // remove the element and put the last element in its place
171 Val last = std::move(_heap_[_nb_elements_ - 1]);
172 _heap_.pop_back();
174
175 if (!_nb_elements_ || (index == _nb_elements_)) return;
176
177 // restore the heap property
178 Size i = index;
179
180 for (Size j = (index << 1) + 1; j < _nb_elements_; i = j, j = (j << 1) + 1) {
181 // let j be the max child
182 if ((j + 1 < _nb_elements_) && _cmp_(_heap_[j + 1], _heap_[j])) ++j;
183
184 // if "last" is smaller than _heap_[j], "last" must be stored at index i
185 if (_cmp_(last, _heap_[j])) break;
186
187 _heap_[i] = std::move(_heap_[j]);
188 }
189
190 _heap_[i] = std::move(last);
191 }
192
193 // removes a given element from the heap (but does not return it)
194 template < typename Val, typename Cmp >
195 void Heap< Val, Cmp >::erase(const Val& val) {
196 // find val in the heap
197 for (Size i = 0; i < _nb_elements_; ++i)
198 if (_heap_[i] == val) {
199 eraseByPos(i);
200 break;
201 }
202 }
203
204 // removes the top of the heap (but does not return it)
205 template < typename Val, typename Cmp >
207 // if the heap is empty, do nothing
208 if (!_nb_elements_) return;
209 eraseByPos(0);
210 }
211
212 // removes the top element from the heap and return it
213 template < typename Val, typename Cmp >
215 if (!_nb_elements_) { GUM_ERROR(NotFound, "empty heap") }
216
217 Val v = _heap_[0];
218 eraseByPos(0);
219 return v;
220 }
221
222 // after inserting an element at the end of the heap, restore heap property
223 template < typename Val, typename Cmp >
225 // get the element at the end of the heap
226 Size i = _nb_elements_ - 1;
227 Val v = std::move(_heap_[i]);
228
229 // restore the heap property
230 for (Size j = (i - 1) >> 1; i && _cmp_(v, _heap_[j]); i = j, j = (j - 1) >> 1)
231 _heap_[i] = std::move(_heap_[j]);
232
233 _heap_[i] = std::move(v);
234
235 return i;
236 }
237
238 // inserts a new (a copy) element in the heap
239 template < typename Val, typename Cmp >
241 // create a new element at the end of the heap
242 _heap_.push_back(val);
244 return _restoreHeap_();
245 }
246
247 // inserts a new (a copy) element in the heap
248 template < typename Val, typename Cmp >
250 // create a new element at the end of the heap
251 _heap_.push_back(std::move(val));
253 return _restoreHeap_();
254 }
255
256 // emplace a new element in the heap
257 template < typename Val, typename Cmp >
258 template < typename... Args >
260 // create a new element at the end of the heap
261 _heap_.emplace_back(std::forward< Args >(args)...);
263 return _restoreHeap_();
264 }
265
266 // indicates whether the heap is empty
267 template < typename Val, typename Cmp >
268 bool Heap< Val, Cmp >::empty() const noexcept {
269 return (_nb_elements_ == 0);
270 }
271
272 // indicates whether the heap contains a given value
273 template < typename Val, typename Cmp >
274 bool Heap< Val, Cmp >::contains(const Val& val) const {
275 for (Size i = 0; i < _nb_elements_; ++i)
276 if (_heap_[i] == val) return true;
277
278 return false;
279 }
280
281 // returns the element at index elt from the heap
282 template < typename Val, typename Cmp >
283 const Val& Heap< Val, Cmp >::operator[](Size index) const {
284 // check if the element exists
285 if (index >= _nb_elements_) { GUM_ERROR(NotFound, "not enough elements in the heap") }
286
287 return _heap_[index];
288 }
289
290 // displays the content of the heap
291 template < typename Val, typename Cmp >
292 std::string Heap< Val, Cmp >::toString() const {
293 bool deja = false;
294 std::stringstream stream;
295 stream << "[";
296
297 for (Size i = 0; i != _nb_elements_; ++i, deja = true) {
298 if (deja) stream << " , ";
299
300 stream << _heap_[i];
301 }
302
303 stream << "]";
304
305 return stream.str();
306 }
307
308 // A \c << operator for Heap
309 template < typename Val, typename Cmp >
310 std::ostream& operator<<(std::ostream& stream, const Heap< Val, Cmp >& heap) {
311 stream << heap.toString();
312 return stream;
313 }
314
315} /* namespace gum */
Heap data structure.
Definition heap.h:141
void eraseTop()
Removes the top of the heap (but does not return it).
Definition heap_tpl.h:206
Val pop()
Removes the top element from the heap and return it.
Definition heap_tpl.h:214
bool empty() const noexcept
Indicates whether the heap is empty.
Definition heap_tpl.h:268
void resize(Size new_size)
Changes the size of the internal structure storing the heap.
Definition heap_tpl.h:161
Size _nb_elements_
The number of elements in the heap.
Definition heap.h:371
bool contains(const Val &) const
Indicates whether the heap contains a given value.
Definition heap_tpl.h:274
Size size() const noexcept
Returns the number of elements in the heap.
Definition heap_tpl.h:149
Size emplace(Args &&... args)
Emplace a new element in the heap and returns its index.
Definition heap_tpl.h:259
~Heap()
Class destructor.
Definition heap_tpl.h:96
Heap< Val, Cmp > & operator=(const Heap< Val, Cmp > &from)
Copy operator.
Definition heap_tpl.h:103
Heap(Cmp compare=Cmp(), Size capacity=GUM_HEAP_DEFAULT_CAPACITY)
Basic constructor: creates an empty heap.
Definition heap_tpl.h:60
Size capacity() const noexcept
Returns the size of the internal structure storing the heap.
Definition heap_tpl.h:155
std::string toString() const
Definition heap_tpl.h:292
void eraseByPos(Size index)
Removes the element positioned at "index" from the heap.
Definition heap_tpl.h:167
const Val & top() const
Returns the element at the top of the heap.
Definition heap_tpl.h:141
Cmp _cmp_
Comparison function.
Definition heap.h:374
void erase(const Val &val)
Removes a given element from the heap (but does not return it).
Definition heap_tpl.h:195
const Val & operator[](Size index_elt) const
Returns the element at index index_elt from the heap.
Definition heap_tpl.h:283
Size _restoreHeap_()
After inserting an element at the end of the heap, restore heap property.
Definition heap_tpl.h:224
std::vector< Val > _heap_
An array storing all the elements of the heap.
Definition heap.h:368
Size insert(const Val &val)
inserts a new element (actually a copy) in the heap and returns its index
Definition heap_tpl.h:240
Exception : the element we looked for cannot be found.
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Heaps definition.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree