Очередь приоритетов - это абстрактный тип данных, который отражает идею контейнера, элементы которого имеют прикрепленные к ним «приоритеты». В начале очереди всегда появляется элемент с наивысшим приоритетом. Если этот элемент удален, следующий элемент с наивысшим приоритетом перемещается вперед.
Стандартная библиотека C ++ определяет шаблон класса priority_queue со следующими операциями:
push : вставить элемент в очередь приоритета.
top : вернуть (не удаляя) элемент с наивысшим приоритетом из очереди приоритетов.
pop : удалить элемент с наивысшим приоритетом из очереди приоритетов.
size : возвращает количество элементов в очереди с приоритетом.
empty : возвращает истину или ложь в зависимости от того, пуста ли очередь с приоритетами.
В следующем фрагменте кода показано, как создать две очереди с приоритетом, одна из которых может содержать целые числа, а другая - строки символов:
#include <queue>
priority_queue<int> q1;
priority_queue<string> q2;
Ниже приведен пример использования приоритетной очереди:
#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;
}
Результат этой программы:
the quick
the lazy dog
jumped over
fox
Поскольку очередь следует дисциплине приоритета, строки печатаются от наивысшего до самого низкого приоритета.
Иногда необходимо создать очередь с приоритетом, чтобы содержать определенные пользователем объекты. В этом случае приоритетной очереди необходимо знать критерий сравнения, используемый для определения того, какие объекты имеют наивысший приоритет. Это делается с помощью объекта функции, принадлежащего классу, который перегружает operator (). Перегруженный () действует как <с целью определения приоритетов. Например, предположим, что мы хотим создать приоритетную очередь для хранения объектов Time. У объекта Time есть три поля: часы, минуты, секунды:
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;
}
}
Очередь с приоритетом для хранения времени в соответствии с вышеуказанным критерием сравнения будет определяться следующим образом:
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;
}
Программа распечатывает время от самого раннего до самого раннего:
5 16 13
5 14 20
3 2 40
3 2 26
Если бы мы хотели, чтобы самые ранние времена имели наивысший приоритет, мы бы переопределили CompareTime следующим образом:
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;
}
};