关于最小生成树的经典算法一个是普里姆算法,另一个就是克鲁斯卡尔算法,在这里和大家一起讨论,有不对的地方希望大家多多指教,先上图
和普里姆算法用一个数组进行比较不同的是,克鲁斯卡尔算法用的是边进行比较,一条边的起始节点,终端 节点,和边的权值
再按权值的大小对边从小大到进行排序,而克鲁斯卡尔算法的核心思想是,要找到最小的生成树,那么就将边从小到大一条一条加进去,只要碰见加进去会出现回环就加,这样从小到大加的边所生成的树那么就一定是最小生成树,那么该算法的核心就是如何判断是否会出现回环,下面请看算法的java实现版
public class GraphKruskal { private Edge[] edges; private int edgeSize; public GraphKruskal(int edgeSize) { this.edgeSize = edgeSize; edges = new Edge[edgeSize]; } public void miniSpanTreeKruskal(){ int m,n,sum=0; int[] parent = new int[edgeSize];//神奇的数组,下标为起点,值为终点 for(int i = 0 ;i<edgeSize;i++){ parent[i] = 0; } for(int i = 0;i<edgeSize;i++){ n = find(parent,edges[i].begin); m = find(parent,edges[i].end); if(n!=m){ parent[n] = m; System.out.println("起始顶点:"+edges[i].begin+"---结束顶点:"+edges[i].end+"~权值:"+edges[i].weight); sum+=edges[i].weight; }else{ System.out.println("第"+i+"条边回环了"); } } System.out.println("sum:"+sum); } /*这是最关键的一步,通过该find方法判断是否能够形成回环 * */ public int find(int[] parent,int f){ while(parent[f]>0){ System.out.println("找到起点"+f); f = parent[f]; System.out.println("找到终点:"+f); } return f; } public void createEdgeArray(){ Edge edge0 = new Edge(4,7,7); Edge edge1 = new Edge(2,8,8); Edge edge2 = new Edge(0,1,10); Edge edge3 = new Edge(0,5,11); Edge edge4 = new Edge(1,8,12); Edge edge5 = new Edge(3,7,16); Edge edge6 = new Edge(1,6,16); Edge edge7 = new Edge(5,6,17); Edge edge8 = new Edge(1,2,18); Edge edge9 = new Edge(6,7,19); Edge edge10 = new Edge(3,4,20); Edge edge11 = new Edge(3,8,21); Edge edge12 = new Edge(2,3,22); Edge edge13 = new Edge(3,6,24); Edge edge14 = new Edge(4,5,26); edges[0] = edge0; edges[1] = edge1; edges[2] = edge2; edges[3] = edge3; edges[4] = edge4; edges[5] = edge5; edges[6] = edge6; edges[7] = edge7; edges[8] = edge8; edges[9] = edge9; edges[10] = edge10; edges[11] = edge11; edges[12] = edge12; edges[13] = edge13; edges[14] = edge14; } class Edge{ private int begin; private int end; private int weight; public Edge(int begin, int end, int weight) { super(); this.begin = begin; this.end = end; this.weight = weight; } public int getBegin() { return begin; } public void setBegin(int begin) { this.begin = begin; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } } public static void main(String[]args){ GraphKruskal graphKruskal = new GraphKruskal(15); graphKruskal.createEdgeArray(); graphKruskal.miniSpanTreeKruskal(); } }