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,
562 if (index >= __nb_elements) {
564 "not enough elements in the PriorityQueueImplementation");
567 return *(__heap[index].second);
571 template <
typename Val,
580 std::stringstream stream;
583 for (
Size i = 0; i != __nb_elements; ++i, deja =
true) {
584 if (deja) stream <<
" , ";
586 stream <<
"(" << __heap[i].first <<
" , " << *(__heap[i].second) <<
")";
595 template <
typename Val,
603 if (index >= __nb_elements) {
605 "not enough elements in the PriorityQueueImplementation");
609 const Val* val = __heap[index].second;
615 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
616 i = j, j = (j - 1) >> 1) {
617 __heap[i] = std::move(__heap[j]);
618 __indices[*(__heap[i].second)] = i;
622 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
624 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
628 if (__cmp(new_priority, __heap[j].first))
break;
631 __heap[i] = std::move(__heap[j]);
632 __indices[*(__heap[i].second)] = i;
636 __heap[i].first = new_priority;
637 __heap[i].second = val;
644 template <
typename Val,
652 if (index >= __nb_elements) {
654 "not enough elements in the PriorityQueueImplementation");
658 const Val* val = __heap[index].second;
664 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
665 i = j, j = (j - 1) >> 1) {
666 __heap[i] = std::move(__heap[j]);
667 __indices[*(__heap[i].second)] = i;
671 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
673 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
677 if (__cmp(new_priority, __heap[j].first))
break;
680 __heap[i] = std::move(__heap[j]);
681 __indices[*(__heap[i].second)] = i;
685 __heap[i].first = std::move(new_priority);
686 __heap[i].second = val;
693 template <
typename Val,
699 const Val& elt,
const Priority& new_priority) {
700 setPriorityByPos(__indices[elt], new_priority);
704 template <
typename Val,
710 const Val& elt, Priority&& new_priority) {
711 setPriorityByPos(__indices[elt], std::move(new_priority));
715 template <
typename Val,
720 INLINE
const Priority&
722 const Val& elt)
const {
723 return __heap[__indices[elt]].first;
727 template <
typename Val,
732 INLINE
const Priority&
735 if (index > __nb_elements) {
737 "not enough elements in the PriorityQueueImplementation");
739 return __heap[index].first;
747 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
750 __indices(capacity >> 1,
true,
true),
752 __heap.reserve(capacity);
759 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
762 std::initializer_list< std::pair< Val, Priority > > list) :
763 __indices(
Size(list.size()) / 2,
true,
true) {
765 __heap.reserve(list.size());
766 for (
const auto& elt : list) {
767 insert(elt.first, elt.second);
775 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
781 __indices(from.__indices), __nb_elements(from.__nb_elements),
788 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
789 template <
typename OtherAlloc >
794 __indices(from.__indices),
795 __nb_elements(from.__nb_elements), __cmp(from.__cmp) {
798 __heap.reserve(from.
__heap.size());
799 for (
const auto& elt : from.
__heap) {
800 __heap.push_back(elt);
809 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
813 __heap(
std::move(from.__heap)),
814 __indices(
std::move(from.__indices)),
815 __nb_elements(
std::move(from.__nb_elements)), __cmp(
std::move(from.__cmp)) {
821 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
829 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
860 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
861 template <
typename OtherAlloc >
879 __heap.reserve(from.
__heap.size());
880 for (
const auto& elt : from.
__heap) {
881 __heap.push_back(elt);
896 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
906 __heap = std::move(from.
__heap);
907 __cmp = std::move(from.
__cmp);
915 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
920 return __heap[0].second;
924 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
925 INLINE
const Priority&
930 return __heap[0].first;
934 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
938 return __nb_elements;
942 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
946 return Size(__heap.capacity());
950 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
954 if (new_size < __nb_elements)
return;
956 __heap.reserve(new_size);
957 __indices.
resize(new_size / 2);
961 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
970 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
973 if (index >= __nb_elements)
return;
976 __indices.
erase(__heap[index].second);
979 std::pair< Priority, Val > last = std::move(__heap[__nb_elements - 1]);
983 if (!__nb_elements || (index == __nb_elements))
return;
988 for (
Size j = (index << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
990 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
994 if (__cmp(last.first, __heap[j].first))
break;
997 __heap[i] = std::move(__heap[j]);
998 __indices[__heap[i].second] = i;
1002 __heap[i] = std::move(last);
1003 __indices[__heap[i].second] = i;
1007 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1012 eraseByPos(__indices[val]);
1017 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1024 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1029 Val v = __heap[0].second;
1036 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1044 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1047 Val val,
const Priority& priority) {
1051 __indices.
insert(val, 0);
1054 __heap.push_back(std::pair< Priority, Val >(priority, val));
1056 __indices.erase(val);
1060 std::pair< Priority, Val > new_heap_val = std::move(__heap[__nb_elements]);
1064 Size i = __nb_elements - 1;
1066 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
1067 i = j, j = (j - 1) >> 1) {
1068 __heap[i] = std::move(__heap[j]);
1069 __indices[__heap[i].second] = i;
1073 __heap[i].first = std::move(new_heap_val.first);
1074 __heap[i].second = val;
1081 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1084 Val val, Priority&& priority) {
1088 __indices.
insert(val, 0);
1091 __heap.push_back(std::pair< Priority, Val >(std::move(priority), val));
1093 __indices.erase(val);
1097 std::pair< Priority, Val > new_heap_val = std::move(__heap[__nb_elements]);
1101 Size i = __nb_elements - 1;
1103 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
1104 i = j, j = (j - 1) >> 1) {
1105 __heap[i] = std::move(__heap[j]);
1106 __indices[__heap[i].second] = i;
1110 __heap[i].first = std::move(new_heap_val.first);
1111 __heap[i].second = val;
1118 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1119 template <
typename... Args >
1123 std::pair< Val, Priority > new_elt =
1124 std::make_pair< Val, Priority >(std::forward< Args >(args)...);
1125 return insert(new_elt.first, std::move(new_elt.second));
1129 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1133 return (__nb_elements == 0);
1137 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1141 return __indices.exists(val);
1145 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1149 if (index >= __nb_elements) {
1151 "not enough elements in the PriorityQueueImplementation");
1154 return __heap[index].second;
1158 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1163 std::stringstream stream;
1166 for (
Size i = 0; i != __nb_elements; ++i, deja =
true) {
1167 if (deja) stream <<
" , ";
1169 stream <<
"(" << __heap[i].first <<
" , " << __heap[i].second <<
")";
1174 return stream.str();
1178 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1182 if (index >= __nb_elements) {
1184 "not enough elements in the PriorityQueueImplementation");
1188 Val val = __heap[index].second;
1194 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
1195 i = j, j = (j - 1) >> 1) {
1196 __heap[i] = std::move(__heap[j]);
1197 __indices[__heap[i].second] = i;
1201 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
1203 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
1207 if (__cmp(new_priority, __heap[j].first))
break;
1210 __heap[i] = std::move(__heap[j]);
1211 __indices[__heap[i].second] = i;
1215 __heap[i].first = new_priority;
1216 __heap[i].second = val;
1223 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1227 if (index >= __nb_elements) {
1229 "not enough elements in the PriorityQueueImplementation");
1233 Val val = __heap[index].second;
1239 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
1240 i = j, j = (j - 1) >> 1) {
1241 __heap[i] = std::move(__heap[j]);
1242 __indices[__heap[i].second] = i;
1246 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
1248 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
1252 if (__cmp(new_priority, __heap[j].first))
break;
1255 __heap[i] = std::move(__heap[j]);
1256 __indices[__heap[i].second] = i;
1260 __heap[i].first = std::move(new_priority);
1261 __heap[i].second = val;
1268 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1270 Val elt,
const Priority& new_priority) {
1271 setPriorityByPos(__indices[elt], new_priority);
1275 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1277 Val elt, Priority&& new_priority) {
1278 setPriorityByPos(__indices[elt], std::move(new_priority));
1282 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1283 INLINE
const Priority&
1286 return __heap[__indices[elt]].first;
1290 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1291 INLINE
const Priority&
1294 if (index > __nb_elements) {
1296 "not enough elements in the PriorityQueueImplementation");
1298 return __heap[index].first;
1306 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1315 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1317 std::initializer_list< std::pair< Val, Priority > > list) :
1324 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1333 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1334 template <
typename OtherAlloc >
1343 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1352 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1359 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1363 Implementation::operator=(from);
1368 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1369 template <
typename OtherAlloc >
1373 Implementation::operator=(from);
1378 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1382 Implementation::operator=(std::move(from));
1387 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
1388 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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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)