Почему для очереди приоритета требуется front(), pop_back() из базового контейнера вместо back(), pop_back()?

Из C++ Primer, а также https://en.cppreference.com/w/cpp/container/priority_queue, я знаю:

Priority_queue требует произвольного доступа в дополнение к фронту, push_back и pop_back;

Я также прочитал это сообщение в блоге от Google и знаю:

  • push: добавьте новый элемент в очередь,
  • pop: удалить самый большой элемент очереди,
  • top: доступ к самому большому элементу очереди.

push должен быть реализован push_back, без проблем. И pop и top похоже, работают на одном элементе. Один из них - доступ к нему, другой - его удаление. Поэтому я думаю, что эти две операции должны быть реализованы с помощью pop_front() и front() или pop_back() и back().

Поэтому я смущен, почему требования front() и pop_back()?

Пусть, например, предположим, что основной контейнер представляет собой vector а некоторые элементы int позволяют сказать 1,2,3,4,5,6. Как интерфейс адаптера " pop(), top() " работает с базовыми " front(), pop_back() "?

Ответ 1

Хотя pop() на priority_queue в конечном счете удаляет верхний элемент, он должен поддерживать инвариант, которого не было бы, если бы все элементы просто переместились. Таким образом, он работает, заменяя верхнее значение с front() на back() и pop_back() и затем заменяя смещенное значение одним из своих дочерних элементов до восстановления инварианта.

Аналогично, push() вызывает push_back() а затем выполняет серию свопов, хотя и в другом направлении.

Примечание: поскольку C++ использует максимальную кучу (в отличие от обычного соглашения), инвариант состоит в том, что любой элемент должен быть больше, чем оба его дочерних элемента (если они существуют). Поскольку большинство полезных проблем связаны с мини-кучей, вы почти всегда должны указывать std::greater<> в качестве аргумента Compare template.