Как работает структура данных priority_queue в C++?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
priority_queue в C++ — это контейнерный адаптер, предоставляющий интерфейс очереди с приоритетами. Он работает следующим образом:
-
Основа: По умолчанию
priority_queueреализована поверх вектора (std::vector) и использует кучу (heap) для управления своими элементами. В частности,std::make_heap,std::push_heapиstd::pop_heapиспользуются для поддержания свойства кучи. -
Куча: Поддерживается свойство максимальной кучи (max-heap) по умолчанию. Это означает, что наибольший элемент всегда находится в корне кучи.
-
Вставка (
push):- Новый элемент добавляется в конец базового контейнера (например, вектора).
- Затем вызывается
std::push_heap, чтобы восстановить свойство кучи. Элемент "поднимается" вверх по дереву кучи до тех пор, пока не окажется на правильной позиции относительно своих родителей и потомков.
-
Извлечение (
pop):- Самый приоритетный (наибольший в случае max-heap) элемент находится в корне (на первой позиции в плоском представлении вектора).
- Чтобы удалить его, последний элемент базового контейнера переносится в корень.
- Реальный корень (который мы хотим удалить) сохраняется.
- Размер базового контейнера уменьшается.
- Затем вызывается
std::pop_heap, которая перемещает новый корневой элемент ("проваливает" его) вниз по дереву, меняя местами с наибольшим из своих потомков до тех пор, пока свойство кучи не будет восстановлено. - Остается только извлечь сохраненный ранее максимальный элемент.
-
Доступ к верхнему элементу (
top): Возвращает ссылку на элемент в корне кучи (наиболее приоритетный). Эта операция не изменяет контейнер. -
Порядок: По умолчанию используется
std::lessдля сравнения элементов, что приводит к max-heap (наибольший элемент имеет наивысший приоритет). Можно указать пользовательский компаратор (например,std::greaterдля min-heap) и базовый контейнер.
Пример использования (max-heap):
#include <queue>
#include <vector>
#include <iostream>
// Пример использования priority_queue (max-heap по умолчанию)
int main() {
std::priority_queue<int> pq; // Основан на std::vector<int> и использует std::less<int>
pq.push(10);
pq.push(30);
pq.push(20);
while (!pq.empty()) {
std::cout << pq.top() << " "; // Доступ к наибольшему элементу
pq.pop(); // Удаление наибольшего элемента
}
// Вывод: 30 20 10
return 0;
}
Пример использования (min-heap):
#include <queue>
#include <vector>
#include <iostream>
#include <functional> // Для std::greater
// Пример использования priority_queue (min-heap)
int main() {
std::priority_queue<int, std::vector<int>, std::greater<int>> pq;
pq.push(10);
pq.push(30);
pq.push(20);
while (!pq.empty()) {
std::cout << pq.top() << " "; // Доступ к наименьшему элементу
pq.pop(); // Удаление наименьшего элемента
}
// Вывод: 10 20 30
return 0;
}
Сложность операций:
| Операция | Средняя сложность | Худшая сложность |
|---|---|---|
| push | O(log N) | O(log N) |
| pop | O(log N) | O(log N) |
| top | O(1) | O(1) |
| empty/size | O(1) | O(1) |
Где N — количество элементов в очереди.