可更新的优先级队列

时间:2013-11-03 06:04:56

标签: c++

C ++标准库中是否有任何内置允许我在数据结构的优先级队列/堆中工作(即,始终可以从列表中弹出最高值,可以定义如何为自定义类确定最高值等等)但是允许我更新堆中的密钥?我正在处理相当简单的数据,确切地说是对,但是我需要能够轻松地更新堆中给定键的值以使我的算法正常运行。什么是在C ++中实现这一目标的最佳方法?

3 个答案:

答案 0 :(得分:3)

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

另一种方法是使用支持更新密钥的不同PQ实现,例如二项式堆。二项式堆具有通过摆动指针而不是移动值来操纵的特殊优点。这简化了实现update-key和delete等操作的任务。

答案 1 :(得分:2)

我不确定你对Boost的看法是什么,但我总是考虑一种几乎标准的库(一些提升功能甚至最终出现在标准库中)。在任何情况下,如果你可以使用boost,那么Boost.Heap提供了一个具有可更新优先级的优先级队列。

与大多数boost库一样,它只是头文件,所以没有链接器麻烦,它不会使你的构建系统变得更复杂。你可以#include使用它。

答案 2 :(得分:-1)

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

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

也就是说,您希望最初使用下面的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函数,以便即时建立这样的排序条件。

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