Kolejka priorytetowa to abstrakcyjny typ danych, który odzwierciedla pojęcie kontenera, którego elementy mają przypisane „priorytety”. Element o najwyższym priorytecie zawsze pojawia się na początku kolejki. Jeśli ten element zostanie usunięty, następny element o najwyższym priorytecie zostanie przeniesiony na pierwszy plan.
Biblioteka standardowa C ++ definiuje szablon klasy priority_queue, z następującymi operacjami:
push : Wstaw element do kolejki priorytetów.
top : Zwróć (bez usuwania) element o najwyższym priorytecie z kolejki priorytetowej.
pop : usuwa element o najwyższym priorytecie z kolejki priorytetów.
size : Zwraca liczbę elementów w kolejce priorytetowej.
empty : Zwraca wartość true lub false w zależności od tego, czy kolejka priorytetowa jest pusta, czy nie.
Poniższy fragment kodu pokazuje, jak utworzyć dwie kolejki priorytetowe, jedną, która może zawierać liczby całkowite, a drugą, która może zawierać ciągi znaków:
#include <queue>
priority_queue<int> q1;
priority_queue<string> q2;
Oto przykład użycia kolejki priorytetowej:
#include <string>
#include <queue>
#include <iostream>
using namespace std;
int main()
{
piority_queue<string> pq;
pq.push("the quick");
pq.push("fox");
pq.push("jumped over");
pq.push("the lazy dog");
while (!pq.empty()) {
cout << pq.top() << endl;
pq.pop();
}
return 0;
}
Wynik tego programu to:
the quick
the lazy dog
jumped over
fox
Ponieważ kolejka podlega dyscyplinie priorytetu, łańcuchy są drukowane od najwyższego do najniższego priorytetu.
Czasami trzeba utworzyć kolejkę priorytetową, aby zawierała obiekty zdefiniowane przez użytkownika. W takim przypadku kolejka priorytetów musi znać kryterium porównania używane do określenia, które obiekty mają najwyższy priorytet. Odbywa się to za pomocą obiektu funkcji należącego do klasy, która przeciąża operator (). Przeciążona () działa jako <na potrzeby określania priorytetów. Na przykład załóżmy, że chcemy utworzyć kolejkę priorytetową do przechowywania obiektów Time. Obiekt Czas ma trzy pola: godziny, minuty, sekundy:
struct Time {
int h;
int m;
int s;
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
}
Kolejka priorytetowa do zapisania czasów według powyższego kryterium porównania byłaby zdefiniowana w następujący sposób:
priority_queue<Time, vector<Time>, CompareTime> pq;
Here is a complete program:
#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
struct Time {
int h;
int m;
int s;
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
};
int main()
{
priority_queue<Time, vector<Time>, CompareTime> pq;
Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};
for (int i = 0; i < 4; ++i)
pq.push(t[i]);
while (! pq.empty()) {
Time t2 = pq.top();
cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
setw(3) << t2.s << endl;
pq.pop();
}
return 0;
}
Program wypisuje czas od ostatniego do najwcześniejszego:
5 16 13
5 14 20
3 2 40
3 2 26
Gdybyśmy chcieli, aby najwcześniejsze czasy miały najwyższy priorytet, przedefiniowalibyśmy opcję CompareTime w następujący sposób:
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t2.h < t1.h) return true;
if (t2.h == t1.h && t2.m < t1.m) return true;
if (t2.h == t1.h && t2.m == t1.m && t2.s < t1.s) return true;
return false;
}
};