【问题标题】:C++ Priority queue to find and modify objects查找和修改对象的 C++ 优先级队列
【发布时间】:2014-11-02 14:37:47
【问题描述】:

我正在尝试实现 A* 算法并且我需要一个优先级队列,但是 std::priority_queue 对我不起作用,因为我需要查找元素(Node 对象)是否在 @ 987654323@ 或不访问其数据并在必要时对其进行修改。

我可以使用std::priority_queue 以某种方式做到这一点吗?

由于我对 std::priority_queue 没有太多经验,因此我将不胜感激代码建议。

【问题讨论】:

  • 你不能使用front()并遍历它吗?
  • boost::bimap 怎么样?
  • 请注意,标准库容器通常会在效率低下时避免提供操作。在通常的优先级队列实现中(使用堆),搜索和成员资格测试具有 O(N) 复杂性,这可能是为什么没有内置提供此操作的原因。这对您的应用程序可能是也可能不是问题。只需注意您需要多久测试一次会员资格。
  • 必须在每个新节点上进行搜索,花费 O(M),M=队列大小。
  • @mariya:通常,当您需要对优先级队列进行成员资格测试时,您会将堆与有效实现此操作的(散列)集结合起来。成本是 O(N) 内存,因此您可以确定这种权衡是否适合您。每次从堆中添加/删除项目时,请确保从集合中添加/删除项目。如果要实现删除,只需从集合中删除项目,并在从堆中弹出它们时忽略不在集合中的项目。如果您需要更新项目,它会变得有点棘手,但它也是可行的。

标签: c++ stl priority-queue


【解决方案1】:

"但是 stl::priority_queue 对我不起作用,因为我需要查找元素(节点对象)是否在 priority_queue 中,以访问其数据并在必要时对其进行修改。”

您可以为任何提供适当Compare 类参数的类很好地做到这一点。

std::priority_queue<T> 要求底层Container 符合SequenceContainer 的概念。

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

您可以获取std::priority_queue&lt;T&gt;::front() 引用的地址,并遍历队列以查找某些实例。


如果您确实需要拥有唯一存在的对象实例,并且应该通过一些优先级算法另外管理,那么存储智能指针(例如std::shared_ptr&lt;T&gt;)而不是值或原始指针可能是一个好主意。当然,Compare 类需要适当调整。


struct CompareNodes {
    bool operator
        ( const std::shared_ptr<Node>& lhs
        , const std::shared_ptr<Node>& rhs
        ) {
        // Provide some operation to compare lhs < rhs (less) results in true
        // This function is meant to determine the actual priority of your Node
        // instances, when referenced in the priority_queue<> in question.
    }
};

std::priority_queue
    < std::shared_ptr<Node>
    , std::vector<std::shared_ptr<Node>>
    , CompareNodes
    > myQueue;

“访问其数据并在必要时对其进行修改。”

如上例所示,使用std::shared_ptr 的优先级队列,还可以让您不必再在队列中查找实例,以及同步原始实例的数据修改。 p>

【讨论】:

  • value_typeclass Compare = std::less&lt;typename Container::value_type&gt; 中应该是什么?
  • @mariya 至于我的样本std::shared_ptr&lt;Node&gt;。您必须自己实现这一点,正如我尝试在我的示例中使用 CompareNodes 演示的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 2012-02-24
相关资源
最近更新 更多