优先级队列和 Prim 算法

Priority queue and Prim's Algorithm

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

我已经阅读了C++参考手册,仍然不清楚如何在STL中使用优先级队列数据结构。

所以,基本上我一直在尝试使用堆来实现我自己的。

我这样做是为了实现Prim的算法。

Vector <int, int> pq;

这是我的优先队列。第一个字段是节点,第二个字段是现有树的权重。

我计划每次向树中添加新节点时,通过更新其相邻节点的权重来修改pq中的权重值。

  • 如何访问此向量的各个元素?我还需要能够随意删除元素

这是实现优先级队列的好方法吗?如果我想在容器中添加另一个字段,即,该怎么办

Vector<int, int, int> MST
  • 如何访问第三个元素?我想以这种方式存储结果MST,使前两个字段表示形成边的顶点,第三个字段表示权重

如果有人能告诉我如何使用push_back将元素分配给这个向量,也会有所帮助。

  • 此外,传统的C++STL优先级队列在这方面有帮助吗?因为每次向MST添加新元素时,我都需要更新优先级值?当值被修改时,它会根据优先级自我校正吗?

  • 另一个问题,这些向量,当我将它们传递给一个函数并试图进行更改时,它是按值传递还是按引用传递?或者,这些更改是否反映在函数之外?

在Prim的算法中,不需要对元素进行随机访问。您只需要跳过队列中已连接并向前传递的元素。

因此算法看起来如下:

  1. 选择节点N
  2. N的所有边添加到PQ
  3. 从PQ中获得最低成本优势
    • 如果它连接的节点已经在树中,跳过它
    • 否则将该边添加到树中,调用新节点N并返回到点2

添加节点后,只需检查树的大小是否已经是size of graph - 1。如果是,那就结束。

请注意,PQ上的唯一操作是add_elementpop_minimum,因此std::priority_queue将起作用。

首先,std::vector<int,int>无效-第二个类型参数是(可选)分配器,int不是分配器。如果您使用的是不同的底层容器,请说明它是什么。我假设您现在想使用std::vector

其次,std::priority_queue不支持您想要的操作(访问和删除任意元素),所以您不能使用它。

您可以直接使用底层向量,并使用堆算法(std::make_heap等)对其进行排序:

  • 随机访问将起作用(尽管不清楚一旦向量按堆顺序排列,索引会是什么)
  • 删除任意元素需要将其从向量中删除并重新运行makeheap,或者您可以实现自己的screenDown

哦,你可以制作一些值类型来存储在你的向量中,比如

std::vector<std::pair<int,int>>

对于你的第一个例子,或者更清楚地说:

struct {
int node;
int weight;
} Node;
// ...
std::vector<Node>