最小生成树的Kruskal算法java代码实现

       思路:1.首先,我们要建立一个带权值的图  

               2.我们按权值大小把所有的边从小到大排列,把排列好的边加入到ArrayList队列中,当然这里可以直接使用数组Edge[] 

               3.然后我们开始选择权值小的边,若不构成圈,即进入到我们的最小生成树的集合中来 

               4.直到我们的最小生成树的结点 = 最小生成树的边数+1,即完成最小生成树

KruskalMST类:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *@author sanjun 
 */
public class KruskalMST {
	
	private int vertexNum; //结点总数
	private List<Edge> edges = new ArrayList<Edge>(); //用于存储图的边
	private Set<String> hs = new HashSet<String>(); //最小生成树结点
	private ArrayList<Edge> edgesMST = new ArrayList<Edge>(); //最小生成树的边数
	
	/**
	 * 初始化图,并按边的权值从小到大排列
	 * @author sanjun
	 * @return 
	 */
	public void sortEdges(){
		
		vertexNum = 8; //初始化结点
		Edge[] e = {new Edge("4","5",0.35),new Edge("4","7",0.37),
				new Edge("5","7",0.28),new Edge("0","7",0.16),
				new Edge("1","5",0.32),new Edge("0","4",0.38),
				new Edge("2","3",0.17),new Edge("1","7",0.19),
				new Edge("0","2",0.26),new Edge("1","2",0.36),
				new Edge("1","3",0.29),new Edge("2","7",0.34),
				new Edge("6","2",0.40),new Edge("3","6",0.52),
				new Edge("6","0",0.58),new Edge("6","4",0.93)}; //带权重的边
		
		Arrays.sort(e);//进行从小到大排列
	
		for(int i = 0;i < e.length;i++){ //把排列好的边加到edges
			edges.add(e[i]);
		}
	}
	
	/**
	 * 首先,遍历edges队列,若该边不构成圈,即把边加入edgesMST中
	 * 直到edgesMST的大小等于总结点数-1
	 * 最后遍历edgesMST中的边,并输出其中信息,和所有边的总权值
	 * @return
	 */
	private void createMST() {
		
		for(int i = 0;i < edges.size();i++){
			Edge edge = edges.get(i);
			if(isCircle(edge)) continue;
			edgesMST.add(edge);
			if(edgesMST.size()==vertexNum-1){
				break;
			}
		}
		
		double sum = 0; //总权值
		for(int i = 0;i < edgesMST.size();i++){
			Edge edge = edgesMST.get(i);
			sum += edge.getWeight();
			System.out.println(edge.getBegin()+"->"+edge.getEnd()+" 权值:"+edge.getWeight());
		}
		System.out.println("总权值:"+sum);
	}
	
	/**
	 * 判断添加该边是否构成圈
	 * @param edge 边
	 * @return boolean
	 */
	private boolean isCircle(Edge edge){
		int size = hs.size(); //最小生成树中的结点数
		
		if(!hs.contains(edge.getBegin())){	//若该端结点不属于hs,即添加该结点到hs,size加1
			hs.add(edge.getBegin());		
			size++;
		}
		if(!hs.contains(edge.getEnd())){
			hs.add(edge.getEnd());
			size++;
		}
		if(size == edgesMST.size()+1){ //若size == 最小生成树的边数+1,即构成圈
			return true;
		}else{
			return false;
		}
	}
	
	public static void main(String[]args){
		
		KruskalMST mst = new KruskalMST();
		mst.sortEdges(); 
		mst.createMST();
		
	}
	
}

Edge类:
/**
 * 带权重的边的数据类型
 * @interface 
 * @author sanjun
 * @Time 2017-05-02
 */
public class Edge implements Comparable<Edge>{
	 private String begin; //顶点之一
	 private String end;   //另一个顶点
	 private double weight; //边的权重
	   
	   public Edge(String begin, String end, double weight) {
		    this.begin = begin;
			this.end = end;
			this.weight = weight;
	   }
		
		public String getBegin() {
			return begin;
		}
		
		public void setBegin(String begin) {
			this.begin = begin;
		}
		
		public String getEnd() {
			return end;
		}
		public void setEnd(String end) {
			this.end = end;
		}
		
		public double getWeight() {
			return weight;
		}
		
		public void setWeight(int weight) {
			this.weight = weight;
		}
		
		public void show(){
			System.out.println(this.getWeight());
		}
		
		/**
		 * 将边进行比较后通过Arrays.sort(Object[] args0)排列
		 * @author sanjun
		 * @param that
		 */
		public int compareTo(Edge that){
			if(this.getWeight() < that.getWeight()) return -1;
			else if(this.getWeight() > that.getWeight()) return +1;
			else return 0;
		}
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值