1. 程式人生 > >演算法java實現--貪心演算法--最小生成樹問題--Kruskal演算法

演算法java實現--貪心演算法--最小生成樹問題--Kruskal演算法

最小生成樹問題(Kruskal演算法)的java實現(貪心演算法)

具體問題描述以及C/C++實現參見網址

http://blog.csdn.net/liufeng_king/article/details/8738161

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 構造最小生成樹(Kruskal演算法)--貪心演算法
 * @author Lican
 *
 */
public class KrusKal {
	/**
	 * 由連通分支組成的集合為U,包括union(a,b);和find(v)的基本運算
	 * @author Administrator
	 *
	 */
	public static class FastUnionFind {
		public int[] u;//陣列用來儲存頂點所屬的集合,用數字表示
		public FastUnionFind(int n){
			u=new int[n+1];
			for(int i=1;i<=n;i++){//初始化,起初每個頂點所屬的集合名稱即相應的頂點數字
				u[i]=i;
			}
		}
		public int find(int x){//找到頂點所屬的集合
			return u[x];
		}
		public void union(int x,int y){//將第二個點歸入第一個點的集合(集合名字用數字表示)
			u[y]=u[x];
		}
	}

	/**
	 * 邊的類
	 * @author Administrator
	 *
	 */
	public static class EdgeNode implements Comparable{
		float weight;//邊的權重
		int u;//邊的左頂點
		int v;//邊的右頂點
		public EdgeNode(int uu,int vv,float ww){
			u=uu;
			v=vv;
			weight=ww;
		}
		@Override
		public int compareTo(Object x) {//升序排序(從小到大),LinkedList的first就指向長度最短的邊
			float xw=((EdgeNode)x).weight;
			if(weight<xw) return -1;
			if(xw==weight) return 0;
			return 1;
		}
	}
	/**
	 * Kruskal演算法
	 * @param n 所有頂點的數目
	 * @param E 邊的集合(所有的邊)
	 * @param t 儲存逐步連通的邊
	 * @return 是否生成了最小生成樹
	 */
	public static boolean kruskal(int n,LinkedList<EdgeNode> E,EdgeNode[] t){
		FastUnionFind U=new FastUnionFind(n);
		int k=0;
		while(k<n-1){//n個頂點,共n-1條邊,因此k<n-1,即k:0,1,2,3....n-1
			EdgeNode x=E.peek();
			int a=U.find(x.u);//邊的左頂點所屬的集合
			int b=U.find(x.v);//邊的右頂點所屬的集合
			if(a!=b){
				t[k++]=x;
				U.union(a, b);
			}
			E.pop();
		}
		for(int i=0;i<k;i++){
			System.out.println("左頂點:"+t[i].u+"; 右頂點:"+t[i].v+"; 長度:"+t[i].weight);
		}
		return (k==n-1);
	}
	public static void main(String[] args) {
		int n=6;
		EdgeNode e1=new EdgeNode(1,2,6);
		EdgeNode e2=new EdgeNode(1,3,1);
		EdgeNode e3=new EdgeNode(1,4,5);
		EdgeNode e4=new EdgeNode(2,3,5);
		EdgeNode e5=new EdgeNode(3,4,5);
		EdgeNode e6=new EdgeNode(2,5,3);
		EdgeNode e7=new EdgeNode(3,5,6);
		EdgeNode e8=new EdgeNode(5,6,6);
		EdgeNode e9=new EdgeNode(3,6,4);
		EdgeNode e10=new EdgeNode(4,6,2);
		LinkedList<EdgeNode> E=new LinkedList<EdgeNode>();
		E.add(e10);
		E.add(e9);
		E.add(e8);
		E.add(e7);
		E.add(e6);
		E.add(e5);
		E.add(e4);
		E.add(e3);
		E.add(e2);
		E.add(e1);
		Collections.sort(E);
		EdgeNode[] t=new EdgeNode[n];
		kruskal(n,E,t);
	}
}
/**
執行結果:
左頂點:1; 右頂點:3; 長度:1.0
左頂點:4; 右頂點:6; 長度:2.0
左頂點:2; 右頂點:5; 長度:3.0
左頂點:3; 右頂點:6; 長度:4.0
左頂點:2; 右頂點:3; 長度:5.0
*/