在计算机科学和图论中,最小生成树(Minimum Spanning Tree,简称MST)是一个非常重要的概念。最小生成树算法在数据结构和算法设计中扮演着重要角色,广泛应用于网络设计、图处理等领域。本文将带你从零开始,深入浅出地学习最小生成树算法的代码实现。
一、什么是最小生成树?
在无向连通图中,最小生成树是一个包含图中所有顶点的极小连通子图,并且其所有边的权值之和最小。换句话说,最小生成树就是连接所有顶点的边权值最小的树。
二、最小生成树算法简介
目前,有许多最小生成树算法,其中最著名的包括:
1. 普里姆算法(Prim算法)
2. 克鲁斯卡尔算法(Kruskal算法)
3. 博斯算法(Bose算法)
本文将重点介绍普里姆算法和克鲁斯卡尔算法的代码实现。
三、普里姆算法
普里姆算法的基本思想是从一个顶点开始,逐步添加边,直到包含所有顶点。在每一步中,都会选择一条连接已生成部分和未生成部分的最小边。
下面是普里姆算法的Python代码实现:
```python
def prim(graph):
graph为邻接矩阵
n = len(graph)
selected = [False] * n 记录顶点是否已选
selected[0] = True
mst = [] 存储最小生成树
while True:
min_weight = float('inf')
u, v = -1, -1
for i in range(n):
if selected[i]:
for j in range(n):
if not selected[j] and graph[i][j]:
if min_weight > graph[i][j]:
min_weight = graph[i][j]
u, v = i, j
if u == -1 and v == -1:
break
selected[v] = True
mst.append((u, v, min_weight))
return mst
测试数据
graph = [
[0, 3, 0, 7, 0],
[3, 0, 8, 5, 0],
[0, 8, 0, 2, 8],
[7, 5, 2, 0, 7],
[0, 0, 8, 7, 0]
]
mst = prim(graph)
print(mst)
```
四、克鲁斯卡尔算法
克鲁斯卡尔算法的基本思想是按照边的权值从小到大排序,每次选择一条边,如果这条边不会形成环,则将其加入到最小生成树中。
下面是克鲁斯卡尔算法的Python代码实现:
```python
def kruskal(graph):
n = len(graph)
mst = []
parent = list(range(n))
rank = [0] * n
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
rootX = find(x)
rootY = find(y)
if rootX != rootY:
if rank[rootX] > rank[rootY]:
parent[rootY] = rootX
elif rank[rootX] < rank[rootY]:
parent[rootX] = rootY
else:
parent[rootY] = rootX
rank[rootX] += 1
edges = sorted(graph, key=lambda x: x[2])
for edge in edges:
u, v, weight = edge
if find(u) != find(v):
mst.append(edge)
union(u, v)
return mst
测试数据
graph = [
[0, 3, 0, 7, 0],
[3, 0, 8, 5, 0],
[0, 8, 0, 2, 8],
[7, 5, 2, 0, 7],
[0, 0, 8, 7, 0]
]
mst = kruskal(graph)
print(mst)
```
五、总结
本文详细介绍了最小生成树算法的两种经典实现:普里姆算法和克鲁斯卡尔算法。通过对这两种算法的代码解析,相信你已经对最小生成树算法有了更深入的理解。在实际应用中,根据具体情况选择合适的算法,可以帮助我们更好地解决问题。