可更新优先级队列

Updateable Priority Queue

本文关键字:队列 优先级 可更新      更新时间:2023-10-16

C++标准库中是否有任何内置内容允许我在类似优先级队列/堆的数据结构中工作(即,可以始终从列表中弹出最高值,可以定义如何为自定义类确定最高值,等等(,但允许我更新堆中的键?我处理的是相当简单的数据,确切地说是对,但我需要能够很容易地更新堆中给定键的值,以便我的算法发挥作用。WHat是在C++中实现这一目标的最佳方式?

二进制堆(在C++标准库中实现优先级队列的方式(不支持任意更新密钥操作。如果更新不频繁,一种常见的方法是从外部将原始项标记为无效,并用新键重新插入该值;当弹出一个无效值时,它将被忽略。

另一种选择是使用不同的PQ实现,它确实支持更新密钥,例如二项式堆。二项式堆具有通过摆动指针而不是移动值来操纵的特殊优势。这简化了执行更新密钥和删除等操作的任务。

我不确定您对Boost的看法是什么,但我一直认为这是一种几乎标准的库(一些Boost功能甚至最终出现在标准库中(。在任何情况下,如果您可以使用boost,那么boost.Hip提供了一个优先级可更新的优先级队列。

像大多数boost库一样,它只是头,所以没有链接器的麻烦,也不会使构建系统变得更加复杂。您只需#include即可使用它。

我没有能力对你的问题发表评论,但这是我的理解。

您提到的,听起来您需要将优先级从对中第一个元素的某些功能更改为第二个元素。

也就是说,您希望最初使用下面的FirstComparator,但随后切换到SecondComparator。

typedef std::pair<X, Y> MyPair;
struct FirstComparator 
{
    bool operator() (const MyPair& left, const MyPair& right) 
    {
        return left.first < right.first;
    }      
}
struct SecondComparator 
{
    bool operator() (const MyPair& left, const MyPair& right) 
    {
        return left.second < right.second;
    }      
}

因为std::priority_queue是一个包含排序标准的模板(正如您的问题所提到的(,所以您可以创建另一个不同类型的容器。(我写的比比较少,所以我们有一个最小堆。(

您需要将会员转移到其中。

std::priority_queue<MyPair, std::vector<MyPair>, FirstComparator> firstQueue;
// Populate and use firstQueue
// Now create an initially-empty queue sorting according to other criterion,
// and copy elements in.
std::priority_queue<MyPair, std::vector<MyPair>, SecondComparator> secondQueue;
// Use 'push' instead of 'emplace' for pre-C++11 code
while (! firstQueue.empty())
    secondQueue.emplace(firstQueue.pop());  
// Use secondQueue

替代方法是使用单个std::vector,并使用不同的排序标准将其与std::sort结合使用。C++11允许您创建命名或匿名的lambda函数,以便动态地建立这样的排序标准。

由于您的问题特别涉及优先级队列,除非您特别感兴趣,否则我不会深入讨论。