使用Go语言实现Prim算法
在本文中,我们将学习如何使用二叉堆方法和优先队列方法在Go语言中实现Prim算法。Prim算法用于查找加权无向图的最小生成树。
算法
步骤1 − 首先,我们需要导入fmt和heap包。然后创建所需的结构体和函数,并为其定义属性。
步骤2 − 接下来,初始化一个空的已访问集合和一个二叉堆h,其中包含从起始顶点s的最小边。
步骤3 − 然后创建main()函数。在函数内部,通过将所需的顶点传递给addEdge()函数来初始化图。
步骤4 − 将顶点传递给在图结构体中创建的函数,并将获得的结果存储在一个单独的变量中。
步骤5 − 最后,使用fmt.Println()函数在屏幕上打印结果。
示例1
在这个例子中,我们将编写一个Go语言程序,使用二叉堆方法实现Prim算法。
package main import ( "container/heap" "fmt" ) type Edge struct { u, v, w int } type Graph struct { n int edges []Edge adj [][]Edge } func (g *Graph) addEdge(u, v, w int) { g.adj[u] = append(g.adj[u], Edge{u, v, w}) g.adj[v] = append(g.adj[v], Edge{v, u, w}) g.edges = append(g.edges, Edge{u, v, w}) } func (g *Graph) prim() int { visited := make([]bool, g.n) h := &EdgeHeap{} heap.Push(h, Edge{-1, 0, 0}) minWeight := 0 for h.Len() > 0 { e := heap.Pop(h).(Edge) if visited[e.v] { continue } visited[e.v] = true minWeight += e.w for _, edge := range g.adj[e.v] { if !visited[edge.v] { heap.Push(h, edge) } } } return minWeight } type EdgeHeap []Edge func (h EdgeHeap) Len() int { return len(h) } func (h EdgeHeap) Less(i, j int) bool { return h[i].w < h[j].w } func (h EdgeHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *EdgeHeap) Push(x interface{}) { *h = append(*h, x.(Edge)) } func (h *EdgeHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func main() { g := &Graph{ n: 5, adj: make([][]Edge, 5), } g.addEdge(0, 1, 2) g.addEdge(0, 3, 6) g.addEdge(1, 2, 3) g.addEdge(1, 3, 8) g.addEdge(1, 4, 5) g.addEdge(2, 4, 7) g.addEdge(3, 4, 9) minWeight := g.prim() fmt.Println("Minimum weight:", minWeight) }
输出
Minimum weight: 16
示例2
在这个例子中,我们将编写一个Go语言程序,使用邻接矩阵和优先队列实现Prim算法。
package main import ( "container/heap" "fmt" ) type Edge struct { v, w int } type Graph struct { n int adjMat [][]int } func (g *Graph) addEdge(u, v, w int) { g.adjMat[u][v] = w g.adjMat[v][u] = w } func (g *Graph) prim() int { visited := make([]bool, g.n) dist := make([]int, g.n) parent := make([]int, g.n) for i := range dist { dist[i] = 1 << 31 // set dist to infinity } dist[0] = 0 h := &VertexHeap{} heap.Push(h, Vertex{0, 0}) minWeight := 0 for h.Len() > 0 { u := heap.Pop(h).(Vertex).v if visited[u] { continue } visited[u] = true minWeight += dist[u] for v := 0; v < g.n; v++ { if g.adjMat[u][v] != 0 && !visited[v] && g.adjMat[u][v] < dist[v] { dist[v] = g.adjMat[u][v] parent[v] = u heap.Push(h, Vertex{v, dist[v]}) } } } return minWeight } type Vertex struct { v, dist int } type VertexHeap []Vertex func (h VertexHeap) Len() int { return len(h) } func (h VertexHeap) Less(i, j int) bool { return h[i].dist < h[j].dist } func (h VertexHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *VertexHeap) Push(x interface{}) { *h = append(*h, x.(Vertex)) } func (h *VertexHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func main() { g := &Graph{ n: 5, adjMat: make([][]int, 5), } for i := range g.adjMat { g.adjMat[i] = make([]int, 5) } g.addEdge(0, 1, 2) g.addEdge(0, 3, 6) g.addEdge(1, 2, 3) g.addEdge(1, 3, 8) g.addEdge(1, 4, 5) g.addEdge(2, 4, 7) g.addEdge(3, 4, 9) minWeight := g.prim() fmt.Println("Minimum weight:", minWeight) }
输出
Minimum weight: 16
结论
我们已经成功地编译并执行了一个Go语言程序来实现Prim算法以及示例。这里我们实现了两个程序。在第一个程序中,我们使用二叉堆方法,而在第二个程序中,我们使用邻接矩阵和优先队列方法。此实现使用邻接矩阵来表示图。它还使用优先队列来维护与已访问集合距离最小的顶点。
广告