Skip to content

Commit 6dbea27

Browse files
committed
add kruskal mst
1 parent 8bd9a4b commit 6dbea27

File tree

5 files changed

+102
-2
lines changed

5 files changed

+102
-2
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ To test each algorithm(data structure), instead of running the file directly, yo
7171
* [EdgeWeightedGraph](edge_weighted_graph.go)
7272
* [LazyPrimMST](lazy_prim_mst.go)
7373
* [PrimMST](prim_mst.go)
74+
* [KruskalMST](kruskal_mst.go)
7475

7576
* 5 STRING
7677

cmd/kruskal-mst/main.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/******************************************************************************
2+
* Execution: go run cmd/kruskal-mst/main.go filename.txt
3+
* Data files: https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
4+
* https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
5+
* https://algs4.cs.princeton.edu/43mst/largeEWG.txt
6+
*
7+
* Compute a minimum spanning forest using a lazy version of Prim's
8+
* algorithm.
9+
*
10+
* % go run cmd/kruskal-mst/main.go tinyEWG.txt
11+
* 0-7 0.16000
12+
* 1-7 0.19000
13+
* 0-2 0.26000
14+
* 2-3 0.17000
15+
* 5-7 0.28000
16+
* 4-5 0.35000
17+
* 6-2 0.40000
18+
* 1.81000
19+
*
20+
* % go run cmd/kruskal-mst/main.go mediumEWG.txt
21+
* 0-225 0.02383
22+
* 49-225 0.03314
23+
* 44-49 0.02107
24+
* 44-204 0.01774
25+
* 49-97 0.03121
26+
* 202-204 0.04207
27+
* 176-202 0.04299
28+
* 176-191 0.02089
29+
* 68-176 0.04396
30+
* 58-68 0.04795
31+
* 10.46351
32+
*
33+
* % go run cmd/kruskal-mst/main.go largeEWG.txt
34+
* ...
35+
* 647.66307
36+
*
37+
******************************************************************************/
38+
39+
package main
40+
41+
import (
42+
"fmt"
43+
"os"
44+
45+
"github.com/shellfly/algo"
46+
"github.com/shellfly/algo/stdin"
47+
)
48+
49+
func main() {
50+
g := algo.NewEdgeWeightedGraph(stdin.NewIn(os.Args[1]))
51+
mst := algo.NewKruskalMST(g)
52+
for _, e := range mst.Edges() {
53+
fmt.Println(e)
54+
}
55+
fmt.Printf("%.5f\n", mst.Weight())
56+
}

cmd/prim-mst/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import (
4545

4646
func main() {
4747
g := algo.NewEdgeWeightedGraph(stdin.NewIn(os.Args[1]))
48-
mst := algo.NewLazyPrimMST(g)
48+
mst := algo.NewPrimMST(g)
4949
for _, e := range mst.Edges() {
5050
fmt.Println(e)
5151
}

kruskal_mst.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package algo
2+
3+
// KruskalMST ...
4+
type KruskalMST struct {
5+
mst *Queue
6+
weight float32
7+
}
8+
9+
// NewKruskalMST ...
10+
func NewKruskalMST(g *EdgeWeightedGraph) *KruskalMST {
11+
mst := NewQueue()
12+
k := &KruskalMST{mst, 0}
13+
pq := NewMinPQ()
14+
for _, e := range g.Edges() {
15+
pq.Insert(e)
16+
}
17+
uf := NewUF(g.V())
18+
for !pq.IsEmpty() && mst.Size() < g.V()-1 {
19+
e := pq.DelMin().(*Edge)
20+
v := e.Either()
21+
w := e.Other(v)
22+
if uf.Connected(v, w) {
23+
continue
24+
}
25+
uf.Union(v, w)
26+
k.mst.Enqueue(e)
27+
k.weight += e.Weight()
28+
}
29+
return k
30+
}
31+
32+
// Weight ...
33+
func (k *KruskalMST) Weight() float32 {
34+
return k.weight
35+
}
36+
37+
// Edges ...
38+
func (k *KruskalMST) Edges() (edges []*Edge) {
39+
for _, e := range k.mst.Slice() {
40+
edges = append(edges, e.(*Edge))
41+
}
42+
return
43+
}

prim_mst.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (l *PrimMST) visit(g *EdgeWeightedGraph, v int) {
6464
if e.Weight() < l.distTo[w] {
6565
l.distTo[w] = e.Weight()
6666
l.edgeTo[w] = e
67-
if !l.pq.Contains(w) {
67+
if l.pq.Contains(w) {
6868
l.pq.DecreaseKey(w, FloatPQItem(l.distTo[w]))
6969
} else {
7070
l.pq.Insert(w, FloatPQItem(l.distTo[w]))

0 commit comments

Comments
 (0)