📅  最后修改于: 2023-12-03 15:33:47.391000             🧑  作者: Mango
Prim's算法是一种用于寻找加权无向连通图的最小生成树的算法。 它是一种贪心算法,因为在每个阶段中,它都选择具有最小边权的边来添加到新的生成树中。
当树涵盖了所有节点时,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)。