为 Prim 在 c++ 中的实现设计数据结构

Designing Data structures for Prim's implementation in c++

本文关键字:实现 数据结构 Prim c++      更新时间:2023-10-16

我正试图在c++中实现Prim的MST算法。我有一个设计问题

我实现了一个最小堆,它接受一个整数,我们可以提取最小值,减少键和插入键。

现在,正如我在Prim的理解,我需要维护每个顶点的权重,邻居信息。我的一些想法是:

1]定义一个结构

struct node {
    int vertex;
    int weight;
    int neighbor;
};

使用最小堆返回权值最小的节点。但问题是减少键,因为对于减少键调用者需要传递他想要减少键的顶点。由于堆频繁地交换元素,我必须遍历整个列表来找到顶点,然后减少它的键值。这是O(n),我认为如果我这样做,Prim会变得更糟。

另一种方法是维护另一个数组,该数组跟踪最小堆队列中顶点的位置。但是在最小堆操作期间跟踪位置会很麻烦。

基本上,如果我必须执行reduce -key(v),如何在基于权重的最小堆队列中找到v。有什么优雅的方法吗?哪一个还能保留复杂性?

基本上确实需要在数据结构之间做一些交叉引用。然而,你写

但是在最小堆操作期间跟踪位置会很麻烦

不太正确。使用下面的代码,您可以重用或编写不需要这个的可重用数据结构。

  1. 首先,您的优先级队列需要公开某种类型的迭代器,允许O(1)访问。为此,您可以直接使用boost.Heap(参见下面的注释),或者从那里获得关于界面应该如何看起来的想法。

  2. 现在使用另一种数据结构,它将(在O(1)中)节点标签映射到队列的迭代器。例如,如果节点标签是(连续的)整数,你可以使用迭代器的vector;如果它们基本上是其他的,你应该使用unordered_map

  3. 每个节点结构还需要包含2中数据结构所使用的标签。

项目3。这意味着您需要在上面的代码中添加以下内容。

struct node {
     ...
     // Identifies
     Label label;
};

请注意,这允许您将优先级队列与其他数据结构解耦。当您执行decrease_key时,您的node在优先级队列中移动,您不需要担心任何事情,因为每个节点都包含label成员。


说了这么多,你还应该考虑简单地使用Boost Graph Library,它已经有了Prim的算法。