Kruskal算法是图论中用于求解最小生成树的算法,算法时间复杂度为O(eloge) 比较起Prim算法,Kruskal算法虽然同求最小生成树,却更适合稀疏网。
这里图的储存结构建议采用边集数组。 为了提高查找最短边的速度,可以先对边集数组按边上的权值排序。
其中kruskal()方法就是算法的实现
public class EdgeArray<T> { /** * 顶点个数 */ protected int vertices_num; /** * 边个数 */ protected int edge_num; /** * 图结点 */ protected T[] vertices; /** * 边集数组 */ protected EdgeArrayNode[] edgeArray; public void kruskal() { int vertex1_root, vertex2_root; //定义parent数组 int parent[] = new int[vertices_num]; //初始化parent数组 for (int i = 0; i < vertices_num; i++) { parent[i] = -1; } //依次考察每一条边 for (int i = 0, num = 0; i < edge_num; i++) { EdgeArrayNode node = edgeArray[i]; vertex1_root = findRoot(parent, node.getFrom()); vertex2_root = findRoot(parent, node.getTo()); //位于不同连通分量 if (vertex1_root != vertex2_root) { System.out.println("生成树第" + (num+1) + "条边:" + vertices[node.getFrom()] + "--" + vertices[node.getTo()] + " : " + node.getWeight()); parent[vertex2_root] = vertex1_root; num++; } } } /** * 求vertex_index的根 * @param parent * @param vertex_index * @return */ private int findRoot(int[] parent, int vertex_index) { int root = vertex_index; while (parent[root] > -1) { root = parent[root]; } return root; } }测试结果
生成树第1条边:v1--v4 : 12 生成树第2条边:v2--v3 : 17 生成树第3条边:v0--v5 : 19 生成树第4条边:v2--v5 : 25 生成树第5条边:v4--v5 : 26结果分析
完整的网图: (1)初始化 得到 {v0}, {v1}, {v2}, {v3}, {v4}, {v5} (2)加入最短边 {v1, v4} 得到 {v0}, {v1, v4}, {v2}, {v3}, {v5}
(3)加入最短边 {v2, v3} 得到 {v0}, {v1, v4}, {v2, v3}, {v5}
(4)加入最短边 {v0, v5} 得到 {v0, v5}, {v1, v4}, {v2, v3}
(5)加入最短边 {v2, v5} 得到 {v0, v5, v2, v3}, {v1, v4}
(6)加入最短边 {v4, v5} 得到 {v0, v5, v2, v3, v1, v4}
上图即为所求的最小生成树