Что такое priority_queue в C++?

Ответ

std::priority_queue — это адаптер контейнера из стандартной библиотеки C++, реализующий очередь с приоритетом. Это не обычная FIFO-очередь: элементы извлекаются в порядке убывания их значения (по умолчанию), то есть элемент с наивысшим приоритетом (максимальным значением) всегда находится наверху.

Основные характеристики:

  • Реализация: Обычно строится поверх std::vector (контейнер по умолчанию) с использованием структуры данных "куча" (heap).
  • Сложность операций:
    • push(): O(log n) — добавление элемента.
    • pop(): O(log n) — удаление верхнего элемента.
    • top(): O(1) — доступ к верхнему элементу.
  • Интерфейс: Не предоставляет итераторов для обхода всех элементов, только доступ к вершине.

Пример использования:

#include <queue>
#include <iostream>

int main() {
    // Очередь с приоритетом по умолчанию (максимальный элемент сверху)
    std::priority_queue<int> maxHeap;

    maxHeap.push(30);
    maxHeap.push(10);
    maxHeap.push(20);

    std::cout << "Top element: " << maxHeap.top() << 'n'; // 30

    // Извлечение всех элементов в порядке убывания
    while (!maxHeap.empty()) {
        std::cout << maxHeap.top() << ' '; // Вывод: 30 20 10
        maxHeap.pop();
    }
    return 0;
}

Кастомизация: Можно изменить порядок и базовый контейнер, передав соответствующие параметры шаблона.

// Очередь с приоритетом, где сверху минимальный элемент
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
minHeap.push(5);
minHeap.push(1);
minHeap.push(3);
std::cout << minHeap.top(); // 1

Ответ 18+ 🔞

Давай разберём эту штуку, std::priority_queue. Представь себе обычную очередь в столовке — кто первый пришёл, тот первый и сожрал. А эта очередь — она, блядь, хитрая жопа. Тут не важно, кто первый пришёл, тут важно, кто круче. Кто с самым большим значением, тот и лезет вперёд, как самый наглый.

Что это за зверь такой? По сути, это не самостоятельный контейнер, а такая обёртка, адаптер. Внутри себя она обычно использует std::vector и выстраивает элементы в кучу (heap), чтобы самый крутой всегда был наверху, под рукой. Удобно, ёпта.

Что она умеет и как быстро?

  • push() — запихнуть элемент. Сложность O(log n). То есть не мгновенно, но и не овердохуища времени займёт.
  • pop() — выкинуть верхний, самый крутой элемент. Тоже O(log n).
  • top() — просто посмотреть, кто там сейчас царь горы. А вот это быстро — O(1). Взял и глянул.
  • ВНИМАНИЕ! Итераторов тут нет, бля. Нельзя пройтись по всем, как по вектору. Только с вершины снимать по одному — вот и весь обход. Сам от себя охуеешь, когда попробуешь её просто так вывести.

Пример, чтобы стало совсем понятно:

#include <queue>
#include <iostream>

int main() {
    // Дефолтная очередь — сверху самый большой элемент (максимальная куча)
    std::priority_queue<int> maxHeap;

    maxHeap.push(30);
    maxHeap.push(10);
    maxHeap.push(20);

    // Кто наверху?
    std::cout << "Top element: " << maxHeap.top() << 'n'; // 30, ебать!

    // Вытаскиваем всех по порядку крутости
    while (!maxHeap.empty()) {
        std::cout << maxHeap.top() << ' '; // Будет: 30, потом 20, потом 10
        maxHeap.pop();
    }
    return 0;
}

А если мне нужно наоборот, чтобы сверху был самый маленький? Без проблем, можно всё настроить. Передаёшь другие параметры шаблона, и получаешь минимальную кучу.

// Теперь сверху будет минимальный элемент. Чистая магия, ёб твою мать.
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
minHeap.push(5);
minHeap.push(1);
minHeap.push(3);
std::cout << minHeap.top(); // 1 — вот он, самый мелкий, уже наверху!

Короче, вещь мощная, когда нужно постоянно работать с самым приоритетным элементом. Но если тебе надо всё сортировать или искать что-то внутри — это не твой инструмент, тут доверия ебать ноль для таких задач. Используй по назначению.