Причина использования `std:: большее` для создания минимальной кучи через`priority_queue`
Мне интересно, почему для создания кучи мин, используя priority_queue
, std::greater
должен быть использован?
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
Для меня, так как наименьшее значение всегда находится в верхней части кучи, занятый класс должен быть std::less
Обновление: с другой стороны, так как поведение по умолчанию priority_queue
(максимальная куча), чтобы держать наибольшее значение на вершине, мне кажется, что std::greater
следует использовать для создания максимальной кучи, а не для создания минимальной кучи
5 ответов
Логический аргумент заключается в следующем
std::priority_queue
контейнерный адаптер; основные соображения памяти делают спину предпочтительным местом для изменений (сpop_back()
а такжеpush_back()
) для контейнеров последовательности, таких какstd::vector
,priority_queue
примитивы основаны наstd::make_heap
(конструктор),std::pop_heap
+container::pop_back
(priority_queue::pop
) и наcontainer::push_back
+std::push_heap
(priority_queue::push
)pop_heap
возьмет переднюю часть основного хранилища и поместит его сзади, впоследствии восстановив инвариант кучи. Обратное идет дляpush_heap
,- дела
sort_heap
наmax_heap
(с максимальным на передней части изначально) будет многократно выталкивать фронт на заднюю часть и сортировать диапазон в соответствии сless
(который является оператором сравнения по умолчанию) - следовательно, предпочтительная реализация
max_heap
должен иметь максимальный элемент по отношению кless
на передней панели, доступ черезpriority_queue::top
(лежащие в основеcontainer::front
). - все еще можно спорить, интуитивно ли это
priority_queue
сstd::less
компаратор представляет собойmax_heap
, Это можно было бы определить какmin_heap
путем изменения аргументов компаратора (но см. комментарий @TC о том, что для связывателей C++98 это довольно многословно) везде при вызовах различных функций кучи. Единственным (для меня) нелогичным результатом было быtop()
тогда бы не дал элемент с высшим приоритетом
Функции кучи C++ make_heap
, push_heap
, а также pop_heap
работать с максимальной кучей, то есть верхний элемент является максимальным при использовании компаратора по умолчанию. Итак, чтобы создать минимальную кучу, вам нужно использовать greater<T>
вместо less<T>
,
Я подозреваю, что максимальная куча используется вместо минимальной кучи, потому что это легче реализовать с less
операция. В C++ less
имеет особую привилегию быть своего рода компаратором по умолчанию для всех алгоритмов STL; если вы собираетесь реализовать только одну операцию сравнения (кроме ==
), так должно быть <
, Это приводит к прискорбной причуде priority_queue<T, C<T>, less<T>>
означает максимальную очередь и priority_queue<T, C<T>, greater<T>>
означает минимальную очередь.
Кроме того, некоторые алгоритмы, такие как nth_element
нужна максимальная куча.
Это процесс, который преобразует приоритетную очередь в отсортированную последовательность.
Как мы можем этого добиться?
Предположим, что теперь у нас есть максимальная куча, мы выполним следующую процедуру.
HEAP-SORT(A)
for i = A.heap_size downto 2
exchange A[1] with A[A.heap_size]
A.heapsize -= 1
max_heapify(A)
Когда мы закончим эту процедуру, мы получим последовательность возрастающего порядка.
Мы замечаем, что каждый раз, когда мы сравниваем два элемента, мы всегда помещаем больший элемент обратно в массив, что означает, что меньший элемент находится слева от большего.
И это соответствует идее, когда мы передаем оператор less в алгоритм std::sort для получения последовательности возрастающего порядка.
A — это структура данных, в которой элементы хранятся таким образом, что элемент с наивысшим приоритетом всегда находится в начале очереди. По умолчанию приоритет элемента определяется его значением. Однако вы можете использовать функтор, чтобы изменить способ определения приоритета элемента.
Функтор — это небольшой функциональный объект, который можно использовать для выполнения определенной задачи. В этом случае функтор используется для сравнения двух целых чисел и возврата значения true, если первое целое число больше второго.
Когда вы используете функтор с
См. http://en.cppreference.com/w/cpp/container/priority_queue. priority_queue
предназначен для того, чтобы поставить наибольшее значение на вершине. Это происходит, если вы используете по умолчанию std::less
компаратор. Итак, если вы хотите обратное поведение, вам нужно использовать обратный компаратор, std::greater
,