Go语言实现最小生成树算法(Minimum Spanning Tree)
在Go语言中实现最小生成树(Minimum Spanning Tree, MST)算法,可以使用Kruskal算法或Prim算法。以下是使用Kruskal算法实现MST的示例代码。
Kruskal算法
Kruskal算法的主要思想是将所有边按照权重从小到大排序,然后逐一添加到生成树中,如果添加一条边会形成环,则跳过这条边,直到生成树中包含所有顶点。
示例代码:
package main
import (
"fmt"
"sort"
)
// 边结构体
type Edge struct {
from, to, weight int
}
// 并查集结构体
type UnionFind struct {
parent, rank []int
}
// 初始化并查集
func NewUnionFind(n int) *UnionFind {
uf := &UnionFind{
parent: make([]int, n),
rank: make([]int, n),
}
for i := range uf.parent {
uf.parent[i] = i
}
return uf
}
// 查找
func (uf *UnionFind) Find(x int) int {
if uf.parent[x] != x {
uf.parent[x] = uf.Find(uf.parent[x])
}
return uf.parent[x]
}
// 合并
func (uf *UnionFind) Union(x, y int) {
rootX := uf.Find(x)
rootY := uf.Find(y)
if rootX != rootY {
if uf.rank[rootX] > uf.rank[rootY] {
uf.parent[rootY] = rootX
} else if uf.rank[rootX] < uf.rank[rootY] {
uf.parent[rootX] = rootY
} else {
uf.parent[rootY] = rootX
uf.rank[rootX]++
}
}
}
// Kruskal算法
func Kruskal(edges []Edge, n int) []Edge {
sort.Slice(edges, func(i, j int) bool {
return edges[i].weight < edges[j].weight
})
uf := NewUnionFind(n)
mst := []Edge{}
for _, edge := range edges {
if uf.Find(edge.from) != uf.Find(edge.to) {
uf.Union(edge.from, edge.to)
mst = append(mst, edge)
}
}
return mst
}
func main() {
edges := []Edge{
{0, 1, 10},
{0, 2, 6},
{0, 3, 5},
{1, 3, 15},
{2, 3, 4},
}
n := 4 // 节点数
mst := Kruskal(edges, n)
fmt.Println("Minimum Spanning Tree:")
for _, edge := range mst {
fmt.Printf("from %d to %d, weight: %d\n", edge.from, edge.to, edge.weight)
}
}
代码解释:
- Edge结构体:表示图中的一条边,包含起点、终点和权重。
- UnionFind结构体:实现并查集数据结构,用于检测环。
- NewUnionFind:初始化并查集。
- Find方法:查找并查集中的代表元。
- Union方法:合并两个集合。
- Kruskal函数:实现Kruskal算法,首先对边按权重排序,然后逐一添加边到生成树中。
- main函数:示例数据,调用Kruskal函数并输出结果。
这个示例代码展示了如何在Go语言中实现Kruskal算法来求解最小生成树。你可以根据需要调整输入的边和节点数。