《算法》第四章部分程序 part 15

▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树

● Kruskal 算法求最小生成树

 1 package package01;
 2 
 3 import edu.princeton.cs.algs4.In;
 4 import edu.princeton.cs.algs4.StdOut;
 5 import edu.princeton.cs.algs4.Edge;
 6 import edu.princeton.cs.algs4.EdgeWeightedGraph;
 7 import edu.princeton.cs.algs4.Queue;
 8 import edu.princeton.cs.algs4.MinPQ;
 9 import edu.princeton.cs.algs4.UF;
10 
11 public class class01
12 {
13     private double weight;
14     private Queue<Edge> mst = new Queue<Edge>();
15 
16     public class01(EdgeWeightedGraph G)
17     {
18         MinPQ<Edge> pq = new MinPQ<Edge>(); // 建立最小优先队列
19         for (Edge e : G.edges())
20             pq.insert(e);
21         for (UF uf = new UF(G.V()); !pq.isEmpty() && mst.size() < G.V() - 1;) // 加入生成树的变得集合
22         {
23             Edge e = pq.delMin();           // 取权值最小的边
24             int v = e.either();
25             int w = e.other(v);
26             if (!uf.connected(v, w))        // 顶点 v 和 w 没有都在树中,说明添加边 v-w 不会构成环
27             {
28                 uf.union(v, w);             // 添加边,更新生成树的权值
29                 mst.enqueue(e);
30                 weight += e.weight();
31             }
32         }
33     }
34 
35     public Iterable<Edge> edges()
36     {
37         return mst;
38     }
39 
40     public double weight()
41     {
42         return weight;
43     }
44 
45     public static void main(String[] args)
46     {
47         In in = new In(args[0]);
48         EdgeWeightedGraph G = new EdgeWeightedGraph(in);
49         class01 mst = new class01(G);
50         for (Edge e : mst.edges())
51             StdOut.println(e);
52         StdOut.printf("%.5f\n", mst.weight());
53     }
54 }

● Boruvka 算法求最小生成树

 1 package package01;
 2 
 3 import edu.princeton.cs.algs4.In;
 4 import edu.princeton.cs.algs4.StdOut;
 5 import edu.princeton.cs.algs4.Edge;
 6 import edu.princeton.cs.algs4.EdgeWeightedGraph;
 7 import edu.princeton.cs.algs4.Bag;
 8 import edu.princeton.cs.algs4.UF;
 9 
10 public class class01
11 {
12     private double weight;
13     private Bag<Edge> mst = new Bag<Edge>();
14 
15     public class01(EdgeWeightedGraph G)
16     {
17         UF uf = new UF(G.V());
18         for (int t = 1; t < G.V() && mst.size() < G.V() - 1; t = t + t) // 重复 v-1 次直到得到生成树
19         {
20             Edge[] closest = new Edge[G.V()];                           // 最小生成树中连接着顶点 v 的边记作 closest[v]
21             for (Edge e : G.edges())
22             {
23                 int v = e.either(), w = e.other(v);
24                 int i = uf.find(v), j = uf.find(w);
25                 if (i == j)                                     // 顶点 v 和 w 来自同一棵树,加入边 v-w 会导致环
26                     continue;
27                 if (closest[i] == null || less(e, closest[i]))  // v 是新顶点,加入边 v-w 会使得 v 的距离比现在小
28                     closest[i] = e;                             // 值标记新距离,还没有加入边
29                 if (closest[j] == null || less(e, closest[j]))  // w 是新顶点,加入边 v-w 会使得 w 的距离比现在小
30                     closest[j] = e;
31             }
32             for (int i = 0; i < G.V(); i++)
33             {
34                 Edge e = closest[i];
35                 if (e != null)                          // 存在连着顶点 v 的最小生成树的边
36                 {
37                     int v = e.either(), w = e.other(v); // 正式加入边 v-w
38                     if (!uf.connected(v, w))            // 防止已经在生成书中的边被再次添加
39                     {
40                         mst.add(e);
41                         weight += e.weight();
42                         uf.union(v, w);
43                     }
44                 }
45             }
46         }
47     }
48 
49     public Iterable<Edge> edges()
50     {
51         return mst;
52     }
53 
54     public double weight()
55     {
56         return weight;
57     }
58     
59     private static boolean less(Edge e, Edge f)         // 比较两条边的权值
60     {
61         return e.weight() < f.weight();
62     }
63 
64     public static void main(String[] args)
65     {
66         In in = new In(args[0]);
67         EdgeWeightedGraph G = new EdgeWeightedGraph(in);
68         class01 mst = new class01(G);
69         for (Edge e : mst.edges())
70             StdOut.println(e);
71         StdOut.printf("%.5f\n", mst.weight());
72     }
73 }

猜你喜欢

转载自www.cnblogs.com/cuancuancuanhao/p/9830174.html