📜  Prim 的最小生成树 (MST) |贪婪算法5(1)

📅  最后修改于: 2023-12-03 15:33:47.391000             🧑  作者: Mango

Prim's最小生成树(MST) | 贪心算法

Prim's算法是一种用于寻找加权无向连通图的最小生成树的算法。 它是一种贪心算法,因为在每个阶段中,它都选择具有最小边权的边来添加到新的生成树中。

步骤
  1. 选择一个顶点并将其添加到树中,将其标记为已访问。
  2. 查找与树中顶点相邻的未标记顶点中具有最小边权的顶点。
  3. 重复第2步,直到树覆盖了所有的顶点。

当树涵盖了所有节点时,Prim's算法就完成了。 返回生成树的所有边和权值的总和。

代码实现
from collections import defaultdict
import heapq

def prim(graph, start):
    """
    :param graph: 无向带权连通图
    :param start: 开始遍历的节点
    :return: 以list形式返回最小生成树,每个元素为一个三元组(edge_weight, start, end)
    """
    # 初始化最小生成树
    mst = []
    # 用于记录已访问的节点
    visited = set([start])
    # 用于记录未访问的边
    edges = [(weight, start, end) for end, weight in graph[start].items()]
    heapq.heapify(edges)

    while edges:
        # 取出当前未访问边中权值最小的边
        weight, start, end = heapq.heappop(edges)

        if end not in visited:
            # end节点未访问过
            visited.add(end)
            mst.append((weight, start, end))

            # 将未访问的边加入edges
            for next_end, next_weight in graph[end].items():
                if next_end not in visited:
                    heapq.heappush(edges, (next_weight, end, next_end))

    return mst
时间复杂度

Prim's算法的时间复杂度取决于优先队列的实现方式。 使用二叉堆实现优先队列,寻找最小边需要O(log V)时间,而且我们需要在每个节点中维护O(E)边的列表。 因此,时间复杂度为O(E log V)。

空间复杂度

Prim's算法的空间复杂度取决于如何表示图形以及如何存储Prim's算法的内部结构。 通常使用邻接矩阵或邻接列表来表示图形。 Prim's算法需要维护一个初始长度为V的visited集合,并且需要将所有边存储在优先队列中。 因此,空间复杂度为O(E + V)。