簡體   English   中英

帶有自定義比較器的最小優先級隊列

[英]Min Priority Queue with custom comparator

我正在使用優先級隊列的排序功能。 該函數是模板化的,並帶有自定義比較器:

template <class T, class Comparator>
void sort (std::vector<T>& myArray, Comparator comp) {}

該函數創建一個優先級隊列:

std::priority_queue<T, std::vector<T>, Comparator > pQueue;

當前, top()pop()返回並彈出最高值。

但是,我正在尋找一個最小優先級隊列,該隊列在使用top()pop()函數時返回並彈出最低值。 我應該怎么做呢?

std::priority_queue是最大堆(默認情況下),並且只有最大的元素可用。 如果希望它是最小堆,則需要反轉排序條件。 因此,如果a < bcomp(a, b)返回true ,則我們需要交換ab來將std::priority_queue轉換為最小堆。 看起來像

template <class T, class Comparator>
void sort (std::vector<T>& myArray, Comparator comp)
{
    auto comp_reverse = [](const auto& lhs, const auto& rhs){ return comp(rhs, lhs); };
    std::priority_queue<T, std::vector<T>, decltype(comp_reverse)> pQueue;
    //...
}

只需交換提供給Comparator對象的參數即可:

auto cmp = [](auto a, auto b) { return Comparator()(b, a); };
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);

請注意,您的Comparator (即std::priority_queueCompare )必須提供嚴格的弱排序

提供嚴格的弱排序的Compare類型。

但是,lambda表達式

auto cmp = [](auto a, auto b) { return !Comparator()(a, b); };

可能無法提供嚴格的弱排序。 例如,如果將Comparator()(a, b)定義為a < b ,則!Comparator()(a, b)等效於!(a < b) ,后者又等效於a >= ba > b絕對不同。

>運算符不同, >=運算符是二進制關系 1 ,由於嚴格意義 2不成立,因此不提供嚴格的弱排序 ,因為a >= a是正確a >= a ,也就是說,它實際上是自反 3


(1) 二進制關系只是二進制謂詞 ,即具有兩個參數的布爾函數,例如,關系運算符或std::less<int>operator()成員函數。

(2)如果二進制關系對某個元素及其本身不成立 ,則稱為嚴格關系,例如< ,因為a < a從未成立。

(3)如果始終對元素及其本身成立二進制關系,則稱其為自反關系,例如<= ,因為a <= a始終成立。

將比較器包裹在交換參數順序的東西中。

a < b等於b > a

template <typename Comparator>
struct invert
{
     template <typename Right, typename Left>
     bool operator()(Right&& rhs, Left&& lhs)
     { return comp(std::forward<Left>(lhs), std::forward<Right>(rhs)); }
     Comparator comp;
};

template <class T, class Comparator>
void sort (std::vector<T>& myArray, Comparator comp) 
{
    std::priority_queue<T, std::vector<T>, invert<Comparator> > pQueue(comp);
    // ...
}

暫無
暫無

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

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