设有一个有n个顶点的连通网N={V,E},最初先构造一个只有n个顶点,没有边的非连通图T={V, E},图中每个顶点自成一个连通分量。当在E中选到一条具有最小权值的边时,若该边的两个顶点落在不同的连通分量上,则将此边加入到T中;否则将此边舍去,重新选择一条权值最小的边。如此重复下去,直到所有顶点在同一个连通分量上为止。
图解
:
package kruskal;
import java.util.ArrayList;
import java.util.List;
public class Kruskal {
public static void main(String[] args) {
//构造图
Graph graph=new Graph(10);
graph.addNode('A');
graph.addNode('B');
graph.addNode('C');
graph.addNode('D');
graph.addNode('E');
graph.addNode('F');
graph.addNode('G');
graph.addNode('H');
graph.addNode('I');
graph.addNode('J');
graph.addEdge(0, 1, 2);
graph.addEdge(0, 5, 10);
graph.addEdge(1, 2, 4);
graph.addEdge(1, 6, 3);
graph.addEdge(1, 7, 6);
graph.addEdge(2, 3, 8);
graph.addEdge(3, 4, 30);
graph.addEdge(3, 9, 21);
graph.addEdge(4, 9, 9);
graph.addEdge(5, 6, 20);
graph.addEdge(7, 8, 7);
graph.addEdge(8, 9, 16);
//获取边集
Edge edge=new Edge();
edge.formart(graph.getEdge());//把图的临界矩阵转化成边集
List<Edge> list=edge.getList();//获取到排序的边集
//
ArrayList<ArrayList<Integer>> tatol=new ArrayList<ArrayList<Integer>>();
for(int i=0;i<list.size();i++){
//获取边的顶点
int start=list.get(i).getStart();
int end=list.get(i).getEnd();
//拿到顶点所属的集合
ArrayList<Integer> s=getIndex(tatol,start);
ArrayList<Integer> e=getIndex(tatol, end);
if(s==null&&e==null){//判断这两个集合
//都不在
ArrayList<Integer> temp=new ArrayList<Integer>();
temp.add(start);
temp.add(end);
tatol.add(temp);
System.out.println(list.get(i));
}else if(s!=null&&e==null){
//start在,而end不再
s.add(end);
System.out.println(list.get(i));
}else if(s==null&&e!=null){
//start不再,end在
e.add(start);
System.out.println(list.get(i));
}else if(s!=null&&e!=null&&s!=e){
//两个都在,在不同的集合中,
ArrayList<Integer> temp=e;
tatol.remove(e);
s.addAll(temp);
System.out.println(list.get(i));
}else if(s!=null&&e!=null&&s==e){
//都在同一集合中
continue;
}
}
System.out.println(tatol.size());
}
//返回顶点所属的集合
public static ArrayList<Integer> getIndex(ArrayList<ArrayList<Integer>> tatol,int index){
for(int i=0;i<tatol.size();i++){
if(tatol.get(i).contains(index)){
return tatol.get(i);
}
}
return null;
}
}