簡體   English   中英

使用 `std::greater` 通過 `priority_queue` 創建最小堆的原因

[英]The reason of using `std::greater` for creating min heap via `priority_queue`

我想知道為什么使用priority_queue創建最小堆,應該使用std::greater

std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;

對我來說,因為最小值總是位於堆的頂部,所以使用的類應該是std::less

更新:另一方面,由於priority_queue (最大堆)的默認行為是在頂部保存最大值,在我看來std::greater應該用於創建最大堆而不是最小堆創建

邏輯論證如下

  1. std::priority_queue是一個容器適配器; 基本內存考慮使 back 成為對序列容器(如std::vector pop_back()進行修改(使用pop_back()push_back() )的首選位置。
  2. priority_queue原語基於std::make_heap (constructor)、 std::pop_heap + container::pop_back ( priority_queue::pop ) 和container::push_back + std::push_heap ( priority_queue::push )
  3. pop_heap會取底層存儲的前面,放在后面,之后恢復堆不變性。 push_heap
  4. sort_heap上的max_heap (具有最大在前面最初)將反復彈出前面到后面和排序根據范圍less (即默認比較運算符)
  5. 因此, max_heap的首選實現是讓 max 元素在前面less ,通過priority_queue::top (底層container::front )訪問。
  6. 人們仍然可以爭論,帶有std::less比較器的priority_queue表示max_heap是否直觀。 它可以通過在對各種堆函數的調用中的任何地方反轉比較器的參數(但請參閱@TC 的評論,使用 C++98 綁定器,這相當冗長)來定義為min_heap 一個(對我來說)違反直覺的結果是top()不會給元素以最高優先級

C++ 堆函數make_heappush_heappop_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需要最大堆。

請參閱http://en.cppreference.com/w/cpp/container/priority_queue priority_queue旨在將最大值放在頂部。 如果您使用默認的std::less比較器,就會發生這種情況。 因此,如果您想要反向行為,則需要使用反向比較器std::greater

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM