aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
heap.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Heaps definition.
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  *
28  */
29 
30 #ifndef GUM_HEAP_H
31 #define GUM_HEAP_H
32 
33 #include <functional>
34 #include <initializer_list>
35 #include <utility>
36 #include <vector>
37 
38 #include <agrum/agrum.h>
39 
40 namespace gum {
41 
42 #define GUM_HEAP_DEFAULT_CAPACITY 10
43 
44  // templates provided by this file
45 
46  template < typename Val, typename Cmp, typename Alloc >
47  class Heap;
48  template < typename Val, typename Cmp, typename Alloc >
49  std::ostream& operator<<(std::ostream&, const Heap< Val, Cmp, Alloc >&);
50 
51  // ===========================================================================
52  // === SIMPLE HEAP DATA STRUCTURE ===
53  // ===========================================================================
54 
55  /**
56  * @class Heap
57  * @headerfile heap.h <agrum/tools/core/heap.h>
58  * @brief Heap data structure
59  * @ingroup basicstruct_group
60  * @ingroup heap_group
61  *
62  * This structure is a basic heap data structure, i.e., it is a container in
63  * which elements are sorted according to a weak ordering. Given this
64  * ordering, we do have access in O(1) to the "smallest" element contained by
65  * the structure. Insertions and deletions of elements are processed in O(ln
66  * n), where n is the number of elements in the heap. In addition to the
67  * classical pop, top and push functions, Heap provide direct accessors to
68  * the elements in the heap (see operator[]). However, these can only be
69  * accessed in read-only mode.
70  * @par Usage example:
71  * @code
72  * // create a heap of integers, the top element is the smallest element
73  * Heap<int> heap1;
74  *
75  * // create a heap of floats, the top element is the greatest
76  * Heap<float> heap2 (std::greater<float>());
77  *
78  * // insert elements into the heap
79  * heap1.insert (8);
80  * heap1.insert (10);
81  * heap1.insert (2);
82  * heap1.insert (23);
83  * heap1.insert (24);
84  * heap1.insert (10);
85  * heap1.insert (10);
86  *
87  * // copy a heap into another
88  * Heap<int> heap2 = heap1;
89  *
90  * // get the number of elements of the heap
91  * std::cerr << heap2.size() << std::endl;
92  *
93  * // get the top element but do not remove it
94  * std::cerr << heap2.top() << std::endl;
95  *
96  * // get and remove the top element of the heap
97  * std::cerr << heap2.pop() << std::endl;
98  *
99  * // remove the top element but do not return it (faster than above)
100  * heap2.eraseTop();
101  *
102  * // erase in heap1 value 8
103  * heap1.eraseByVal (8);
104  *
105  * // erase element at position 3 (see function erase for the
106  * // meaning of position 3)
107  * heap1.erase (3);
108  *
109  * // get the element at position 3
110  * heap1[3];
111  *
112  * // check whether element 24 belongs to the heap
113  * heap1.contains (24);
114  * @endcode
115  *
116  * @tparam Val The gum::Heap values type.
117  * @tparam Cmp The comperator used to sort elements in the gum::Heap.
118  * @tparam Alloc The allocator of elements stored in the gum::Heap.
119  */
120  template < typename Val,
121  typename Cmp = std::less< Val >,
122  typename Alloc = std::allocator< Val > >
123  class Heap {
124  public:
125  /// Types for STL compliance
126  /// @{
127  using value_type = Val;
128  using reference = Val&;
129  using const_reference = const Val&;
130  using pointer = Val*;
131  using const_pointer = const Val*;
132  using size_type = std::size_t;
133  using difference_type = std::ptrdiff_t;
134  using allocator_type = Alloc;
135  /// @}
136 
137  // ============================================================================
138  /// @name Constructors / Destructors
139  // ============================================================================
140  /// @{
141 
142  /**
143  * @brief Basic constructor: creates an empty heap.
144  * @param compare a function taking two elements in argument, say e1 and
145  * e2, and returning a Boolean indicating wether e1 < e2, i.e., whether e1
146  * should be nearer than e2 to the top of the heap.
147  * @param capacity the size of the internal data structures containing the
148  * elements (could be for instance vectors or hashtables).
149  */
150  explicit Heap(Cmp compare = Cmp(), Size capacity = GUM_HEAP_DEFAULT_CAPACITY);
151 
152  /**
153  * @brief Initializer list constructor.
154  * @param list The initializer list.
155  */
156  explicit Heap(std::initializer_list< Val > list);
157 
158  /**
159  * @brief Copy constructor.
160  * @param from The gum::Heap to copy.
161  */
162  Heap(const Heap< Val, Cmp, Alloc >& from);
163 
164  /**
165  * @brief Generalized copy constructor.
166  * @tparam OtherAlloc The other gum::Heap allocator.
167  * @param from The gum::Heap to copy.
168  */
169  template < typename OtherAlloc >
170  Heap(const Heap< Val, Cmp, OtherAlloc >& from);
171 
172  /**
173  * @brief Move constructor.
174  * @param from The gum::Heap to move.
175  */
176  Heap(Heap< Val, Cmp, Alloc >&& from) noexcept;
177 
178  /**
179  * @brief Class destructor.
180  */
181  ~Heap();
182 
183  /// @}
184  // ============================================================================
185  /// @name Operators
186  // ============================================================================
187  /// @{
188 
189  /**
190  * @brief Copy operator.
191  *
192  * When a problem occurs during the copy (for instance when not enough
193  * memory is available), the operator guarantees that the heap stays in a
194  * coherent state. Actually, the heap becomes empty. An exception is then
195  * thrown.
196  *
197  * @param from The gum::Heap to copy.
198  */
199  Heap< Val, Cmp, Alloc >& operator=(const Heap< Val, Cmp, Alloc >& from);
200 
201  /**
202  * @brief Generalized copy operator.
203  *
204  * When a problem occurs during the copy (for instance when not enough
205  * memory is available), the operator guarantees that the heap stays in a
206  * coherent state. Actually, the heap becomes empty. An exception is then
207  * thrown.
208  *
209  * @tparam OtherAlloc The other gum::Heap allocator.
210  * @param from The gum::Heap to copy.
211  */
212  template < typename OtherAlloc >
213  Heap< Val, Cmp, Alloc >& operator=(const Heap< Val, Cmp, OtherAlloc >& from);
214 
215  /**
216  * @brief Move operator.
217  *
218  * When a problem occurs during the copy (for instance when not enough
219  * memory is available), the operator guarantees that the heap stays in a
220  * coherent state. Actually, the heap becomes empty. An exception is then
221  * thrown.
222  *
223  * @param from The gum::Heap to move.
224  */
225  Heap< Val, Cmp, Alloc >& operator=(Heap< Val, Cmp, Alloc >&& from) noexcept;
226 
227  /**
228  * @brief Returns the element at index index_elt from the heap.
229  *
230  * @param index_elt The index of the element to return.
231  * @return Returns the element at index index_elt from the heap.
232  * @throw NotFound exception is thrown if there is no element
233  * at position "index_elt".
234  */
235  const Val& operator[](Size index_elt) const;
236 
237  /// @}
238  // ============================================================================
239  /// @name Accessors / Modifiers
240  // ============================================================================
241  /// @{
242 
243  /**
244  * @brief Returns the element at the top of the heap.
245  * @return Returns the element at the top of the heap.
246  * @throw NotFound exception is thrown if the heap is empty.
247  */
248  const Val& top() const;
249 
250  /**
251  * @brief Removes the top element from the heap and return it.
252  * @return Returns the top element from the heap.
253  * @throw NotFound exception is thrown if the heap is empty.
254  */
255  Val pop();
256 
257  /**
258  * @brief Removes the top of the heap (but does not return it).
259  *
260  * If the heap is empty, it does nothing (in particular, it does not throw
261  * any exception).
262  */
263  void eraseTop();
264 
265  /**
266  * @brief Removes the element positioned at "index" from the heap.
267  *
268  * If the element cannot be found, the function returns without throwing
269  * any exception. @param index represents the position of the element to
270  * be removed. This is computed as follows: suppose that the heap is a
271  * complete binary tree, that is, a binary tree where all levels are
272  * completely filled except, maybe, the last one and, in this case, the
273  * elements of this level are all to the left of the tree. Then parsing the
274  * tree from top to bottom and, for each level, from left to right, and
275  * assigning index 0 to the root of the tree and, incrementing the index by
276  * 1 each time we jump to another node, we get a unique index for each
277  * element. This is precisely what the index passed in argument of the
278  * function represents.
279  *
280  * @param index The index of the element to remove
281  */
282  void eraseByPos(Size index);
283 
284  /**
285  * @brief Removes a given element from the heap (but does not return it).
286  *
287  * If the element cannot be found, the function returns without throwing
288  * any exception.
289  *
290  * @param val The element we wish to remove. If the heap contains several
291  * times this element, then the one with the smallest index is removed.
292  */
293  void erase(const Val& val);
294 
295  /**
296  * @brief inserts a new element (actually a copy) in the heap and returns
297  * its index
298  *
299  * @param val The element to insert.
300  * @return The inserted element position in the gum::Heap.
301  */
302  Size insert(const Val& val);
303 
304  /**
305  * @brief Inserts a new element (by moving it) in the heap and returns its
306  * index.
307  *
308  * @param val The element to insert.
309  * @return The inserted element position in the gum::Heap.
310  */
311  Size insert(Val&& val);
312 
313  /**
314  * @brief Emplace a new element in the heap and returns its index.
315  *
316  * @tparam Args the type of the new element to emplace.
317  * @param args The new element to emplace.
318  * @return The emplaced element position in the gum::Heap.
319  */
320  template < typename... Args >
321  Size emplace(Args&&... args);
322 
323  /**
324  * @brief Returns the number of elements in the heap.
325  * @return Returns the number of elements in the heap.
326  */
327  Size size() const noexcept;
328 
329  /**
330  * @brief Indicates whether the heap is empty.
331  * @return Indicates whether the heap is empty.
332  */
333  bool empty() const noexcept;
334 
335  /**
336  * @brief Indicates whether the heap contains a given value.
337  * @return Indicates whether the heap contains a given value.
338  */
339  bool contains(const Val&) const;
340 
341  /**
342  * @return Displays the content of the heap.
343  * @return Returns a std::string representing the content of the heap.
344  */
345  std::string toString() const;
346 
347  /// @}
348  // ============================================================================
349  /// @name Fine tuning
350  // ============================================================================
351  /// @{
352 
353  /**
354  * @brief Returns the size of the internal structure storing the heap.
355  * @return Returns the size of the internal structure storing the heap.
356  */
357  Size capacity() const noexcept;
358 
359  /**
360  * @brief Changes the size of the the internal structure storing the heap.
361  *
362  * If the new size does not enable the heap to contain the elements it
363  * currently contains, then the resizing does not occur.
364  *
365  * @param new_size The gum::Heap new size.
366  */
367  void resize(Size new_size);
368 
369  /// @}
370 
371  private:
372  /// An array storing all the elements of the heap.
373  std::vector< Val, Alloc > heap__;
374 
375  /// The number of elements in the heap.
377 
378  /// Comparison function.
379  Cmp cmp__;
380 
381  /// After inserting an element at the end of the heap, restore heap property
383  };
384 
385 } /* namespace gum */
386 
387 
388 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
389 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
390 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
391 extern template class gum::Heap< int >;
392 # endif
393 # endif
394 #endif
395 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
396 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
397 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
398 extern template class gum::Heap< long >;
399 # endif
400 # endif
401 #endif
402 
403 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
404 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
405 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
406 extern template class gum::Heap< double >;
407 # endif
408 # endif
409 #endif
410 
411 
412 // always include the implementation of the templates
413 #include <agrum/tools/core/heap_tpl.h>
414 
415 #endif /* GUM_HEAP_H */
bool contains(const Val &) const
Indicates whether the heap contains a given value.
Definition: heap_tpl.h:303
Heap(Heap< Val, Cmp, Alloc > &&from) noexcept
Move constructor.
Definition: heap_tpl.h:82
Heap(std::initializer_list< Val > list)
Initializer list constructor.
Definition: heap_tpl.h:47
bool empty() const noexcept
Indicates whether the heap is empty.
Definition: heap_tpl.h:297
Heap(Cmp compare=Cmp(), Size capacity=GUM_HEAP_DEFAULT_CAPACITY)
Basic constructor: creates an empty heap.
Definition: heap_tpl.h:38
#define GUM_HEAP_DEFAULT_CAPACITY
Definition: heap.h:42
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
const Val & operator[](Size index_elt) const
Returns the element at index index_elt from the heap.
Definition: heap_tpl.h:312
Val pop()
Removes the top element from the heap and return it.
Definition: heap_tpl.h:243
Cmp cmp__
Comparison function.
Definition: heap.h:379
Size restoreHeap__()
After inserting an element at the end of the heap, restore heap property.
Definition: heap_tpl.h:253
std::vector< Val, Alloc > heap__
An array storing all the elements of the heap.
Definition: heap.h:373
Size emplace(Args &&... args)
Emplace a new element in the heap and returns its index.
Definition: heap_tpl.h:288
~Heap()
Class destructor.
Definition: heap_tpl.h:91
Size nb_elements__
The number of elements in the heap.
Definition: heap.h:376
void erase(const Val &val)
Removes a given element from the heap (but does not return it).
Definition: heap_tpl.h:224
std::string toString() const
Definition: heap_tpl.h:323
Size size() const noexcept
Returns the number of elements in the heap.
Definition: heap_tpl.h:178
Heap< Val, Cmp, Alloc > & operator=(Heap< Val, Cmp, Alloc > &&from) noexcept
Move operator.
Definition: heap_tpl.h:157
Heap< Val, Cmp, Alloc > & operator=(const Heap< Val, Cmp, OtherAlloc > &from)
Generalized copy operator.
Definition: heap_tpl.h:126
Size insert(const Val &val)
inserts a new element (actually a copy) in the heap and returns its index
Definition: heap_tpl.h:269
Size insert(Val &&val)
Inserts a new element (by moving it) in the heap and returns its index.
Definition: heap_tpl.h:278
void eraseTop()
Removes the top of the heap (but does not return it).
Definition: heap_tpl.h:235
Heap(const Heap< Val, Cmp, Alloc > &from)
Copy constructor.
Definition: heap_tpl.h:59
Heap< Val, Cmp, Alloc > & operator=(const Heap< Val, Cmp, Alloc > &from)
Copy operator.
Definition: heap_tpl.h:99
Size capacity() const noexcept
Returns the size of the internal structure storing the heap.
Definition: heap_tpl.h:184
void resize(Size new_size)
Changes the size of the the internal structure storing the heap.
Definition: heap_tpl.h:190
void eraseByPos(Size index)
Removes the element positioned at "index" from the heap.
Definition: heap_tpl.h:196
Heap(const Heap< Val, Cmp, OtherAlloc > &from)
Generalized copy constructor.
Definition: heap_tpl.h:68
const Val & top() const
Returns the element at the top of the heap.
Definition: heap_tpl.h:170