39 template <
typename Val,
46 __indices(capacity >> 1, true, true),
48 __heap.reserve(capacity);
55 template <
typename Val,
62 std::initializer_list< std::pair< Val, Priority > > list) :
63 __indices(
Size(list.size()) / 2, true, true) {
65 __heap.reserve(list.size());
66 for (
const auto& elt: list) {
67 insert(elt.first, elt.second);
75 template <
typename Val,
85 __indices(from.__indices), __nb_elements(from.__nb_elements),
88 for (
const auto& elt: __indices) {
89 __heap[elt.second].second = &(elt.first);
97 template <
typename Val,
102 template <
typename OtherAlloc >
107 __indices(from.__indices),
108 __nb_elements(from.__nb_elements), __cmp(from.__cmp) {
111 __heap.reserve(from.
__heap.size());
112 for (
const auto& elt: from.
__heap) {
113 __heap.push_back(elt);
115 for (
const auto& elt: __indices) {
116 __heap[elt.second].second = &(elt.first);
125 template <
typename Val,
133 __heap(
std::move(from.__heap)),
134 __indices(
std::move(from.__indices)),
135 __nb_elements(
std::move(from.__nb_elements)), __cmp(
std::move(from.__cmp)) {
141 template <
typename Val,
153 template <
typename Val,
177 for (
const auto& elt: __indices) {
178 __heap[elt.second].second = &(elt.first);
193 template <
typename Val,
198 template <
typename OtherAlloc >
216 __heap.reserve(from.
__heap.size());
217 for (
const auto& elt: from.
__heap) {
218 __heap.push_back(elt);
220 for (
const auto& elt: __indices) {
221 __heap[elt.second].second = &(elt.first);
236 template <
typename Val,
249 __indices = std::move(from.__indices);
250 __heap = std::move(from.__heap);
251 __cmp = std::move(from.__cmp);
252 __nb_elements = std::move(from.__nb_elements);
259 template <
typename Val,
268 return *(__heap[0].second);
272 template <
typename Val,
277 INLINE
const Priority&
282 return __heap[0].first;
286 template <
typename Val,
294 return __nb_elements;
298 template <
typename Val,
306 return Size(__heap.capacity());
310 template <
typename Val,
318 if (new_size < __nb_elements)
return;
320 __heap.reserve(new_size);
321 __indices.
resize(new_size / 2);
325 template <
typename Val,
338 template <
typename Val,
345 if (index >= __nb_elements)
return;
348 __indices.
erase(*(__heap[index].second));
351 std::pair< Priority, const Val* > last = std::move(__heap[__nb_elements - 1]);
355 if (!__nb_elements || (index == __nb_elements))
return;
360 for (
Size j = (index << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
362 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
366 if (__cmp(last.first, __heap[j].first))
break;
369 __heap[i] = std::move(__heap[j]);
370 __indices[*(__heap[i].second)] = i;
374 __heap[i] = std::move(last);
375 __indices[*(__heap[i].second)] = i;
379 template <
typename Val,
387 eraseByPos(__indices[val]);
392 template <
typename Val,
403 template <
typename Val,
411 Val v = *(__heap[0].second);
418 template <
typename Val,
430 template <
typename Val,
437 const Val& val,
const Priority& priority) {
445 std::pair< Priority, const Val* >(priority, &new_elt.first));
447 __indices.erase(val);
451 std::pair< Priority, const Val* > new_heap_val =
452 std::move(__heap[__nb_elements]);
456 Size i = __nb_elements - 1;
458 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
459 i = j, j = (j - 1) >> 1) {
460 __heap[i] = std::move(__heap[j]);
461 __indices[*(__heap[i].second)] = i;
465 __heap[i].first = std::move(new_heap_val.first);
466 __heap[i].second = &(new_elt.first);
473 template <
typename Val,
480 Val&& val, Priority&& priority) {
484 __indices.
insert(std::move(val), 0);
488 std::pair< Priority, const Val* >(std::move(priority), &(new_elt.first)));
490 __indices.erase(new_elt.first);
494 std::pair< Priority, const Val* > new_heap_val =
495 std::move(__heap[__nb_elements]);
499 Size i = __nb_elements - 1;
501 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
502 i = j, j = (j - 1) >> 1) {
503 __heap[i] = std::move(__heap[j]);
504 __indices[*(__heap[i].second)] = i;
508 __heap[i].first = std::move(new_heap_val.first);
509 __heap[i].second = &(new_elt.first);
516 template <
typename Val,
521 template <
typename... Args >
525 std::pair< Val, Priority > new_elt =
526 std::make_pair< Val, Priority >(std::forward< Args >(args)...);
527 return insert(std::move(new_elt.first), std::move(new_elt.second));
531 template <
typename Val,
539 return (__nb_elements == 0);
543 template <
typename Val,
550 const Val& val)
const {
551 return __indices.exists(val);
555 template <
typename Val,
563 if (index >= __nb_elements) {
565 "not enough elements in the PriorityQueueImplementation");
568 return *(__heap[index].second);
572 template <
typename Val,
581 std::stringstream stream;
584 for (
Size i = 0; i != __nb_elements; ++i, deja =
true) {
585 if (deja) stream <<
" , ";
587 stream <<
"(" << __heap[i].first <<
" , " << *(__heap[i].second) <<
")";
596 template <
typename Val,
604 if (index >= __nb_elements) {
606 "not enough elements in the PriorityQueueImplementation");
610 const Val* val = __heap[index].second;
616 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
617 i = j, j = (j - 1) >> 1) {
618 __heap[i] = std::move(__heap[j]);
619 __indices[*(__heap[i].second)] = i;
623 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
625 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
629 if (__cmp(new_priority, __heap[j].first))
break;
632 __heap[i] = std::move(__heap[j]);
633 __indices[*(__heap[i].second)] = i;
637 __heap[i].first = new_priority;
638 __heap[i].second = val;
645 template <
typename Val,
653 if (index >= __nb_elements) {
655 "not enough elements in the PriorityQueueImplementation");
659 const Val* val = __heap[index].second;
665 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
666 i = j, j = (j - 1) >> 1) {
667 __heap[i] = std::move(__heap[j]);
668 __indices[*(__heap[i].second)] = i;
672 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
674 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
678 if (__cmp(new_priority, __heap[j].first))
break;
681 __heap[i] = std::move(__heap[j]);
682 __indices[*(__heap[i].second)] = i;
686 __heap[i].first = std::move(new_priority);
687 __heap[i].second = val;
694 template <
typename Val,
700 const Val& elt,
const Priority& new_priority) {
701 setPriorityByPos(__indices[elt], new_priority);
705 template <
typename Val,
711 const Val& elt, Priority&& new_priority) {
712 setPriorityByPos(__indices[elt], std::move(new_priority));
716 template <
typename Val,
721 INLINE
const Priority&
723 const Val& elt)
const {
724 return __heap[__indices[elt]].first;
728 template <
typename Val,
733 INLINE
const Priority&
736 if (index > __nb_elements) {
738 "not enough elements in the PriorityQueueImplementation");
740 return __heap[index].first;
748 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
751 __indices(capacity >> 1,
true,
true),
753 __heap.reserve(capacity);
760 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
763 std::initializer_list< std::pair< Val, Priority > > list) :
764 __indices(
Size(list.size()) / 2,
true,
true) {
766 __heap.reserve(list.size());
767 for (
const auto& elt: list) {
768 insert(elt.first, elt.second);
776 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
782 __indices(from.__indices), __nb_elements(from.__nb_elements),
789 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
790 template <
typename OtherAlloc >
795 __indices(from.__indices),
796 __nb_elements(from.__nb_elements), __cmp(from.__cmp) {
799 __heap.reserve(from.
__heap.size());
800 for (
const auto& elt: from.
__heap) {
801 __heap.push_back(elt);
810 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
814 __heap(
std::move(from.__heap)),
815 __indices(
std::move(from.__indices)),
816 __nb_elements(
std::move(from.__nb_elements)), __cmp(
std::move(from.__cmp)) {
822 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
830 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
861 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
862 template <
typename OtherAlloc >
880 __heap.reserve(from.
__heap.size());
881 for (
const auto& elt: from.
__heap) {
882 __heap.push_back(elt);
897 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
907 __heap = std::move(from.
__heap);
908 __cmp = std::move(from.
__cmp);
916 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
921 return __heap[0].second;
925 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
926 INLINE
const Priority&
931 return __heap[0].first;
935 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
939 return __nb_elements;
943 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
947 return Size(__heap.capacity());
951 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
955 if (new_size < __nb_elements)
return;
957 __heap.reserve(new_size);
958 __indices.
resize(new_size / 2);
962 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
971 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
974 if (index >= __nb_elements)
return;
977 __indices.
erase(__heap[index].second);
980 std::pair< Priority, Val > last = std::move(__heap[__nb_elements - 1]);
984 if (!__nb_elements || (index == __nb_elements))
return;
989 for (
Size j = (index << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
991 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
995 if (__cmp(last.first, __heap[j].first))
break;
998 __heap[i] = std::move(__heap[j]);
999 __indices[__heap[i].second] = i;
1003 __heap[i] = std::move(last);
1004 __indices[__heap[i].second] = i;
1008 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1013 eraseByPos(__indices[val]);
1018 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1025 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1030 Val v = __heap[0].second;
1037 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1045 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1048 Val val,
const Priority& priority) {
1052 __indices.
insert(val, 0);
1055 __heap.push_back(std::pair< Priority, Val >(priority, val));
1057 __indices.erase(val);
1061 std::pair< Priority, Val > new_heap_val = std::move(__heap[__nb_elements]);
1065 Size i = __nb_elements - 1;
1067 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
1068 i = j, j = (j - 1) >> 1) {
1069 __heap[i] = std::move(__heap[j]);
1070 __indices[__heap[i].second] = i;
1074 __heap[i].first = std::move(new_heap_val.first);
1075 __heap[i].second = val;
1082 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1085 Val val, Priority&& priority) {
1089 __indices.
insert(val, 0);
1092 __heap.push_back(std::pair< Priority, Val >(std::move(priority), val));
1094 __indices.erase(val);
1098 std::pair< Priority, Val > new_heap_val = std::move(__heap[__nb_elements]);
1102 Size i = __nb_elements - 1;
1104 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
1105 i = j, j = (j - 1) >> 1) {
1106 __heap[i] = std::move(__heap[j]);
1107 __indices[__heap[i].second] = i;
1111 __heap[i].first = std::move(new_heap_val.first);
1112 __heap[i].second = val;
1119 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1120 template <
typename... Args >
1124 std::pair< Val, Priority > new_elt =
1125 std::make_pair< Val, Priority >(std::forward< Args >(args)...);
1126 return insert(new_elt.first, std::move(new_elt.second));
1130 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1134 return (__nb_elements == 0);
1138 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1142 return __indices.exists(val);
1146 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1150 if (index >= __nb_elements) {
1152 "not enough elements in the PriorityQueueImplementation");
1155 return __heap[index].second;
1159 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1164 std::stringstream stream;
1167 for (
Size i = 0; i != __nb_elements; ++i, deja =
true) {
1168 if (deja) stream <<
" , ";
1170 stream <<
"(" << __heap[i].first <<
" , " << __heap[i].second <<
")";
1175 return stream.str();
1179 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1183 if (index >= __nb_elements) {
1185 "not enough elements in the PriorityQueueImplementation");
1189 Val val = __heap[index].second;
1195 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
1196 i = j, j = (j - 1) >> 1) {
1197 __heap[i] = std::move(__heap[j]);
1198 __indices[__heap[i].second] = i;
1202 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
1204 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
1208 if (__cmp(new_priority, __heap[j].first))
break;
1211 __heap[i] = std::move(__heap[j]);
1212 __indices[__heap[i].second] = i;
1216 __heap[i].first = new_priority;
1217 __heap[i].second = val;
1224 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1228 if (index >= __nb_elements) {
1230 "not enough elements in the PriorityQueueImplementation");
1234 Val val = __heap[index].second;
1240 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
1241 i = j, j = (j - 1) >> 1) {
1242 __heap[i] = std::move(__heap[j]);
1243 __indices[__heap[i].second] = i;
1247 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
1249 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
1253 if (__cmp(new_priority, __heap[j].first))
break;
1256 __heap[i] = std::move(__heap[j]);
1257 __indices[__heap[i].second] = i;
1261 __heap[i].first = std::move(new_priority);
1262 __heap[i].second = val;
1269 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1271 Val elt,
const Priority& new_priority) {
1272 setPriorityByPos(__indices[elt], new_priority);
1276 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1278 Val elt, Priority&& new_priority) {
1279 setPriorityByPos(__indices[elt], std::move(new_priority));
1283 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1284 INLINE
const Priority&
1287 return __heap[__indices[elt]].first;
1291 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1292 INLINE
const Priority&
1295 if (index > __nb_elements) {
1297 "not enough elements in the PriorityQueueImplementation");
1299 return __heap[index].first;
1307 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1316 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1318 std::initializer_list< std::pair< Val, Priority > > list) :
1325 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1334 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1335 template <
typename OtherAlloc >
1344 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1353 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1360 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1364 Implementation::operator=(from);
1369 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1370 template <
typename OtherAlloc >
1374 Implementation::operator=(from);
1379 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1383 Implementation::operator=(std::move(from));
1388 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1389 INLINE std::ostream&
INLINE std::ostream & operator<<(std::ostream &stream, const PriorityQueue< Val, Priority, Cmp, Alloc > &queue)
The internal class for representing priority queues.
Size __nb_elements
The number of elements in the heap.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
void erase(const Val &val)
Removes a given element from the priority queue (but does not return it).
HashTable< Val, Size, IndexAllocator > __indices
A hashtable for quickly finding the elements by their value.
A priorityQueue is a heap in which each element has a mutable priorityA priority queue is quite simil...
std::string toString() const
Displays the content of the queue.
std::vector< std::pair< Priority, const Val *>, HeapAllocator > __heap
An array storing all the elements of the heap as well as their score.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
void resize(Size new_size)
Changes the size of the internal structure storing the priority queue.
void clear()
Removes all the elements from the queue.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
friend class PriorityQueueImplementation
All gum::PriorityQueueImplementation are friends with themselves.
Cmp __cmp
Comparison function.
#define GUM_ERROR(type, msg)