This repository has been archived by the owner on Feb 7, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprioqueue.h
91 lines (79 loc) · 3.02 KB
/
prioqueue.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <set>
// Eintrag einer Vorrangwarteschlange, bestehend aus einer Priorität
// prio mit Typ P und zusätzlichen Daten data mit Typ D.
// Die Priorität prio darf nicht direkt, sondern nur durch Aufruf
// von changePrio verändert werden.
// (Aus bestimmten Gründen ist es praktischer, dass Entry global und
// nicht innerhalb von PrioQueue definiert wird.)
template <typename P, typename D>
struct Entry {
P prio;
D data;
// Initialisierung mit Priorität p und zusätzlichen Daten d.
Entry (P p, D d) : prio(p), data(d) {}
};
// Minimum-Vorrangwarteschlange mit Prioritäten des Typs P
// und zusätzlichen Daten des Typs D.
// An der Stelle, an der PrioQueue für einen bestimmten Typ P verwendet
// wird, muss ein Kleiner-Operator (<) für den Typ P bekannt sein.
// Andere Vergleichsoperatoren (<=, >, >=, ==, !=) werden nicht benötigt.
template <typename P, typename D>
struct PrioQueue {
using Entry = ::Entry<P, D>;
struct LessThan {
bool operator() (Entry* e1, Entry* e2) const {
if (e1->prio < e2->prio) return true;
if (e2->prio < e1->prio) return false;
return e1 < e2;
}
};
std::set<Entry*, LessThan> entries;
// Ist die Warteschlange momentan leer?
bool isEmpty () {
return entries.empty();
}
// Neuen Eintrag mit Priorität p und zusätzlichen Daten d erzeugen,
// zur Warteschlange hinzufügen und zurückliefern.
// (Von insert erzeugte Einträge müssen vom Anwender freigegeben
// werden, nachdem sie mit extractMinimum oder remove aus der
// Warteschlange entfernt wurden und nicht mehr gebraucht werden.)
Entry* insert (P p, D d) {
Entry* e = new Entry(p, d);
entries.insert(e);
return e;
}
// Eintrag mit minimaler Priorität liefern.
// (Nullzeiger bei einer leeren Warteschlange.)
Entry* minimum () {
if (entries.empty()) return nullptr;
return *entries.begin();
}
// Eintrag mit minimaler Priorität liefern
// und aus der Warteschlange entfernen (aber nicht freigeben).
// (Bei einer leeren Halde wirkungslos mit Nullzeiger als Resultatwert.)
Entry* extractMinimum () {
Entry* e = minimum();
if (e) entries.erase(entries.begin());
return e;
}
// Enthält die Warteschlange den Eintrag e?
// (Resultatwert false, wenn e ein Nullzeiger ist.)
bool contains (Entry* e) {
return entries.count(e);
}
// Eintrag e aus der Warteschlange entfernen (aber nicht freigeben).
// (Wirkungslos mit Resultatwert false, wenn e ein Nullzeiger ist
// oder e nicht zur aktuellen Warteschlange gehört.)
bool remove (Entry* e) {
return entries.erase(e);
}
// Priorität des Eintrags e auf p ändern.
// (Wirkungslos mit Resultatwert false, wenn e ein Nullzeiger ist
// oder e nicht zur aktuellen Warteschlange gehört.)
bool changePrio (Entry* e, P p) {
if (!remove(e)) return false;
e->prio = p;
entries.insert(e);
return true;
}
};