zoukankan      html  css  js  c++  java
  • 《算法》第四章部分程序 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
    ", 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
    ", mst.weight());
    72     }
    73 }
  • 相关阅读:
    让tabgroup在下方显示
    titanium好的学习网站推荐
    代码积累
    Ti.include和require的异同
    Titanium基本介绍
    Java微信支付开发之扫码支付模式一
    Java微信公众平台开发之用户管理(用户基本信息和关注列表)
    Java微信支付开发之公众号支付(微信内H5调起支付)
    Java微信公众平台开发之自定义菜单
    Java微信支付开发之扫码支付模式二
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9830174.html
Copyright © 2011-2022 走看看