我正在使用优先级队列的排序功能。该函数已模板化,并带有自定义比较器:
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()
函数时返回并弹出最小值。我应该怎么做?
答案 0 :(得分:2)
std::priority_queue
是最大堆(默认情况下),并且只有最大的元素可用。如果希望它是最小堆,则需要反转排序条件。因此,如果comp(a, b)
如果true
会返回a < b
,则我们需要交换a
和b
以将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;
//...
}
答案 1 :(得分: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 < b
,则!Comparator()(a, b)
将等效于!(a < b)
,而后者又等效于a >= b
,并且绝对不同于a > b
。
与>
运算符不同,>=
运算符是二进制关系 1 ,它不提供严格弱排序 em>,因为 strictness 2 不成立,因为确实a >= a
(即实际上是反身 ) 3 。
(1)二进制关系只是一个二进制谓词,即具有两个参数的布尔函数,例如关系运算符或{{ {} {1}}的成员函数。
(2)二进制关系,如果它从不对表示保留,则称为严格,例如operator()
,因为std::less<int>
永不成立。
(3)二进制关系,如果它对于元素及其本身始终保持,则称为自反,例如<
,因为a < a
总是成立。
答案 2 :(得分:0)
将比较器包裹在交换参数顺序的地方。
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);
// ...
}