具有自定义比较器的最小优先级队列

Posted

技术标签:

【中文标题】具有自定义比较器的最小优先级队列【英文标题】:Min Priority Queue with custom comparator 【发布时间】:2018-10-23 13:28:10 【问题描述】:

我正在研究使用优先级队列的排序功能。该函数是模板化的,并接受自定义比较器:

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() 函数时返回并弹出最小值。我该怎么做呢?

【问题讨论】:

将比较器的返回值改为负数? (使用! 很遗憾无法更改比较器 为什么?你想要一个低优先级队列而不是高优先级队列,然后使用相反的比较器,就是这样。 我运行它的测试用例具有无法更改的比较器 你想通过使pop()top() 不是给定比较器的行为方式来实现什么? 【参考方案1】:

std::priority_queue 是一个最大堆(默认),只有最大的元素可用。如果你希望它是一个最小堆,那么你需要反转排序条件。因此,如果comp(a, b) 将返回true 如果a &lt; b 则我们需要交换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;
    //...

【讨论】:

【参考方案2】:

只需交换给您的Comparator 对象的参数:

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

请注意,您的Comparator(即Compare in std::priority_queue)必须提供严格的弱排序

Compare 类型提供严格的弱排序。

然而,lambda 表达式

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

可能不提供严格的弱排序。例如,如果Comparator()(a, b) 被定义为a &lt; b,那么!Comparator()(a, b) 将等价于!(a &lt; b),而!(a &lt; b) 又等价于a &gt;= b,并且绝对不同于a &gt; b

&gt; 运算符不同,&gt;= 运算符是一个二元关系1,它不提供严格的弱排序,因为strictness2 不成立,因为 a &gt;= a 是真的,即它实际上是 reflexive3


(1) 二元关系 只是一个二元谓词,即一个带有两个参数的布尔函数,例如关系运算符或@987654338 @std::less&lt;int&gt;的成员函数。

(2) 一个二元关系被称为 strict,如果它对于一个元素和它自己从不持有,例如,&lt;,因为a &lt; a 永远不会成立。

(3) 一个二元关系被称为自反,如果它对于一个元素和它自己总是成立,例如&lt;=,因为a &lt;= a 始终成立。

【讨论】:

【参考方案3】:

将比较器包装在交换参数顺序的东西中。

a &lt; b 完全等于b &gt; 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);
    // ...

【讨论】:

以上是关于具有自定义比较器的最小优先级队列的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义比较器声明 C++ 优先级队列的问题

优先队列的自定义比较功能

将自定义比较器传递到 Cython 中的优先级队列

具有自定义排序的优先队列

Stall Reservations 贪心+自定义优先级的优先队列(求含不重叠子序列的多个序列最小值问题)

优先队列自定义比较器