32 #include <agrum/tools/core/heap.h> 37 template <
typename Val,
typename Cmp,
typename Alloc >
38 Heap< Val, Cmp, Alloc >::Heap(Cmp compare, Size capacity) : cmp__(compare) {
39 heap__.reserve(capacity);
42 GUM_CONSTRUCTOR(Heap);
46 template <
typename Val,
typename Cmp,
typename Alloc >
47 Heap< Val, Cmp, Alloc >::Heap(std::initializer_list< Val > list) {
48 heap__.reserve(list.size());
49 for (
const auto& elt: list) {
54 GUM_CONSTRUCTOR(Heap);
58 template <
typename Val,
typename Cmp,
typename Alloc >
59 Heap< Val, Cmp, Alloc >::Heap(
const Heap< Val, Cmp, Alloc >& from) :
60 heap__(from.heap__), nb_elements__(from.nb_elements__), cmp__(from.cmp__) {
66 template <
typename Val,
typename Cmp,
typename Alloc >
67 template <
typename OtherAlloc >
68 Heap< Val, Cmp, Alloc >::Heap(
const Heap< Val, Cmp, OtherAlloc >& from) :
69 nb_elements__(from.nb_elements__), cmp__(from.cmp__) {
70 heap__.reserve(nb_elements__);
73 for (
unsigned i = 0; i < nb_elements__; ++i)
74 heap__.push_back(from.heap__[i]);
81 template <
typename Val,
typename Cmp,
typename Alloc >
82 Heap< Val, Cmp, Alloc >::Heap(Heap< Val, Cmp, Alloc >&& from)
noexcept :
83 heap__(std::move(from.heap__)), nb_elements__(std::move(from.nb_elements__)),
84 cmp__(std::move(from.cmp__)) {
90 template <
typename Val,
typename Cmp,
typename Alloc >
91 Heap< Val, Cmp, Alloc >::~Heap() {
97 template <
typename Val,
typename Cmp,
typename Alloc >
98 Heap< Val, Cmp, Alloc >&
99 Heap< Val, Cmp, Alloc >::operator=(
const Heap< Val, Cmp, Alloc >& from) {
103 heap__ = from.heap__;
113 nb_elements__ = from.nb_elements__;
123 template <
typename Val,
typename Cmp,
typename Alloc >
124 template <
typename OtherAlloc >
125 Heap< Val, Cmp, Alloc >&
126 Heap< Val, Cmp, Alloc >::operator=(
const Heap< Val, Cmp, OtherAlloc >& from) {
132 if (heap__.capacity() < from.nb_elements__)
133 heap__.reserve(from.nb_elements__);
135 for (
unsigned int i = 0; i < from.nb_elements__; ++i) {
136 heap__.push_back(from.heap__[i]);
145 nb_elements__ = from.nb_elements__;
155 template <
typename Val,
typename Cmp,
typename Alloc >
156 Heap< Val, Cmp, Alloc >&
157 Heap< Val, Cmp, Alloc >::operator=(Heap< Val, Cmp, Alloc >&& from)
noexcept {
160 heap__ = std::move(from.heap__);
161 nb_elements__ = std::move(from.nb_elements__);
162 cmp__ = std::move(from.cmp__);
169 template <
typename Val,
typename Cmp,
typename Alloc >
170 INLINE
const Val& Heap< Val, Cmp, Alloc >::top()
const {
171 if (!nb_elements__) { GUM_ERROR(NotFound,
"empty heap"); }
177 template <
typename Val,
typename Cmp,
typename Alloc >
178 INLINE Size Heap< Val, Cmp, Alloc >::size()
const noexcept {
179 return nb_elements__;
183 template <
typename Val,
typename Cmp,
typename Alloc >
184 INLINE Size Heap< Val, Cmp, Alloc >::capacity()
const noexcept {
185 return Size(heap__.size());
189 template <
typename Val,
typename Cmp,
typename Alloc >
190 INLINE
void Heap< Val, Cmp, Alloc >::resize(Size new_size) {
191 if (new_size > nb_elements__) heap__.reserve(new_size);
195 template <
typename Val,
typename Cmp,
typename Alloc >
196 void Heap< Val, Cmp, Alloc >::eraseByPos(Size index) {
197 if (index >= nb_elements__)
return;
200 Val last = std::move(heap__[nb_elements__ - 1]);
204 if (!nb_elements__ || (index == nb_elements__))
return;
209 for (Size j = (index << 1) + 1; j < nb_elements__; i = j, j = (j << 1) + 1) {
211 if ((j + 1 < nb_elements__) && cmp__(heap__[j + 1], heap__[j])) ++j;
214 if (cmp__(last, heap__[j]))
break;
216 heap__[i] = std::move(heap__[j]);
219 heap__[i] = std::move(last);
223 template <
typename Val,
typename Cmp,
typename Alloc >
224 INLINE
void Heap< Val, Cmp, Alloc >::erase(
const Val& val) {
226 for (Size i = 0; i < nb_elements__; ++i)
227 if (heap__[i] == val) {
234 template <
typename Val,
typename Cmp,
typename Alloc >
235 INLINE
void Heap< Val, Cmp, Alloc >::eraseTop() {
237 if (!nb_elements__)
return;
242 template <
typename Val,
typename Cmp,
typename Alloc >
243 INLINE Val Heap< Val, Cmp, Alloc >::pop() {
244 if (!nb_elements__) { GUM_ERROR(NotFound,
"empty heap"); }
252 template <
typename Val,
typename Cmp,
typename Alloc >
253 Size Heap< Val, Cmp, Alloc >::restoreHeap__() {
255 Size i = nb_elements__ - 1;
256 Val v = std::move(heap__[i]);
259 for (Size j = (i - 1) >> 1; i && cmp__(v, heap__[j]); i = j, j = (j - 1) >> 1)
260 heap__[i] = std::move(heap__[j]);
262 heap__[i] = std::move(v);
268 template <
typename Val,
typename Cmp,
typename Alloc >
269 INLINE Size Heap< Val, Cmp, Alloc >::insert(
const Val& val) {
271 heap__.push_back(val);
273 return restoreHeap__();
277 template <
typename Val,
typename Cmp,
typename Alloc >
278 Size Heap< Val, Cmp, Alloc >::insert(Val&& val) {
280 heap__.push_back(std::move(val));
282 return restoreHeap__();
286 template <
typename Val,
typename Cmp,
typename Alloc >
287 template <
typename... Args >
288 Size Heap< Val, Cmp, Alloc >::emplace(Args&&... args) {
290 heap__.emplace_back(std::forward< Args >(args)...);
292 return restoreHeap__();
296 template <
typename Val,
typename Cmp,
typename Alloc >
297 INLINE
bool Heap< Val, Cmp, Alloc >::empty()
const noexcept {
298 return (nb_elements__ == 0);
302 template <
typename Val,
typename Cmp,
typename Alloc >
303 INLINE
bool Heap< Val, Cmp, Alloc >::contains(
const Val& val)
const {
304 for (Size i = 0; i < nb_elements__; ++i)
305 if (heap__[i] == val)
return true;
311 template <
typename Val,
typename Cmp,
typename Alloc >
312 INLINE
const Val& Heap< Val, Cmp, Alloc >::operator[](Size index)
const {
314 if (index >= nb_elements__) {
315 GUM_ERROR(NotFound,
"not enough elements in the heap");
318 return heap__[index];
322 template <
typename Val,
typename Cmp,
typename Alloc >
323 std::string Heap< Val, Cmp, Alloc >::toString()
const {
325 std::stringstream stream;
328 for (Size i = 0; i != nb_elements__; ++i, deja =
true) {
329 if (deja) stream <<
" , ";
340 template <
typename Val,
typename Cmp,
typename Alloc >
341 INLINE std::ostream& operator<<(std::ostream& stream,
342 const Heap< Val, Cmp, Alloc >& heap) {
343 stream << heap.toString();