思路: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;
}
}