最小生成树☞kruskal算法

最小生成树☞kruskal算法:

今天总结一下最小生成树的另一种方法: kruskal算法。它与prim的算法的思路有所不同,prim算法利用了切分定理,而它的思路比较简单,就是从剩下的边中不断寻找最短边,最终构成一棵树。
下面我们首先来分析一下:

思路分析


从图中的步骤我们可以看出,我们需要首先把这张图的所有边存放到一种数据结构中,每次取出权值最小的那一条,如果这条边的两个定点通过其它点能够连接到一块,那么它就不是最小生成树的边,因为这样它会形成环;如果这两个顶点不能够通过其它顶点连到一块儿,那么它就必然属于最小生成树的一条边,因此我们还需要另外一种数据结构来判断任意两点是否是连接的,也就是并查集;而对于边的存储,我们可以使用最小堆,下面我们代码来实现一下。

代码实现:

public class KruskalMST<Weight extends Number & Comparable > {	
/**图的引用*/
  private WeightedGraph<Weight> G;
  /**最小堆*/
  private MinHeapWeight>> minHeap;
  /**生成最小树所有的边*/
  private VectorWeight>> mst;
  /**最小生成树的权值*/
  private Number mstWeight;

 public KruskalMST(WeightedGraph<Weight> g) {
      G = g;
      mst = new Vector<>();
      this.minHeap = new MinHeap<>(G.E());
    /**将图中的所有边存放到一个最小堆中*/
      for(int i=0;i<G.V();i++){
	for(Edge<Weight> e : g.adj(i)){
	   if(i<e.getOther(i)){             //避免重复将边加入到堆中
	         minHeap.insert(e);
                 }
	      }

	}
	/** 创建一个并查集, 来查看已经访问的节点的联通情况,如果是联通的必然会构成一个环*/
  UnionFind unionFind = new UnionFind(G.V());
  while (!minHeap.isEmpty()&& mst.size() < g.V() - 1 ){
	 Edge<Weight> e = minHeap.pop();
	       /**如果两个顶点是连接的。则仍掉这条边*/
         if(unionFind.isConnected(e.a(),e.b())){
	  continue;
        }
          mst.add(e);
        /**将两个顶点并起来*/
         unionFind.unionElements(e.a(),e.b());
   }
        mstWeight = mst.get(0).wt();

        for(int i=1;i<mst.size();i++){
	     mstWeight =  mstWeight.doubleValue() + mst.get(i).wt().doubleValue();
         }

   }
	  /**返回构成最小生成树边的集合*/
  public VectorWeight>> getMst(){
      return mst;
  }

	/***返回最小生成树的权值*/
  public Number getMstWeight(){
      return mstWeight;
  }


posted @ 2019-07-06 15:33  BingoJ  阅读(157)  评论(0编辑  收藏  举报