最小生成树
/** 02. * 定义基本数据结构 03. * @author 小宇 04. */ 05. 06.public class MGraph 07.{ 08. //当边edges[i][j]不存在时,用null表示其值 09. public static final int NULL = 1000; 10. static final int MAXV = 100; 11. //边集 12. int[][] edges = new int[this.MAXV][this.MAXV]; 13. //顶点数,和边数 14. int n,e; 15.}
/** 02. * 该结构用于克鲁斯卡尔算法 03. * @author 小宇 04. */ 05.public class EStruct implements Comparable<EStruct> 06.{ 07. int begin; 08. int end; 09. int weight; 10. //用于给List<EStruct>排序,实现接口comparable方法 11. public int compareTo(EStruct e) 12. { 13. return this.weight - e.weight; 14. } 15. 16.}
/** 02. * 生成邻接矩阵并输出 03. * @author 小宇 04. * 05. */ 06. 07.public class CreateGraph { 08. public void createMat(MGraph g, int A[][], int n) 09. { 10. int i, j; 11. g.n = n; 12. g.e = 0; 13. for(i = 0; i < n; i++) 14. for(j = 0; j < n; j++) 15. { 16. g.edges[i][j] = A[i][j]; 17. if(g.edges[i][j] != 1000) 18. g.e++; 19. } 20. } 21. //--------------------------------------------------- 22. public void DispMat(MGraph g) 23. { 24. int i, j; 25. for(i = 0; i < g.n; i++) 26. { 27. for(j = 0; j < g.n; j++) 28. if(g.edges[i][j] == g.NULL) 29. System.out.print("-" + " "); 30. else 31. System.out.print(g.edges[i][j] + " "); 32. System.out.println(); 33. } 34. } 35. 36.}
import java.util.ArrayList; 02.import java.util.Collections; 03.import java.util.List; 04./** 05. * 核心算法 06. * 用prim算法及克鲁斯卡尔算法求解最小生成树 07. * @author 小宇 08. * 09. */ 10.public class MinimalSpanningTree { 11. 12. static final int INF = 32767; 13. 14. private List<EStruct> eArray = new ArrayList<EStruct>(); 15. 16. //--------------------------------Prim算法-------------------------------- 17. public void Prim(MGraph g, int v) 18. { 19. int[] lowcost = new int[g.n]; 20. int min; 21. int[] closest = new int[g.n]; 22. int i,j,k = 0; 23. for(i = 0; i < g.n; i++) 24. { 25. lowcost[i] = g.edges[v][i]; 26. closest[i] = v; 27. } 28. for(i = 1; i < g.n; i++) 29. { 30. min = INF; 31. for(j = 0; j < g.n; j++) 32. if(lowcost[j] != 0 && lowcost[j] < min) 33. { 34. min = lowcost[j]; 35. k = j; 36. } 37. System.out.println( "边" + closest[k] + "," + k + "权值" + min); 38. lowcost[closest[k]] = 0; 39. lowcost[k] = 0; 40. for(j = 0; j < g.n; j++) 41. if(g.edges[k][j] != 0 && g.edges[k][j] < lowcost[j]) 42. { 43. lowcost[j] = g.edges[k][j]; 44. closest[j] = k; 45. } 46. } 47. } 48. //---------------------克鲁斯卡尔算法----------------------------------------------- 49. public void getEStruct(MGraph mgraph) 50. { 51. /** 52. * 用EStruct结构保存每条边 53. * 最后存于EStruct数组 54. * 然后用java类库提供方法排序 55. */ 56. for(int i = 0;i < mgraph.n; i++) 57. { 58. for(int j = 0; j < mgraph.n; j++) 59. { 60. //由于是无向图 61. if(j < i) 62. { 63. //如果begin:i , end: j ,的边存在 64. if(mgraph.edges[i][j] != mgraph.NULL) 65. { 66. //创建EStruct保存该边信息并加入List:eArray 67. EStruct estruct = new EStruct(); 68. estruct.begin = i; 69. estruct.end = j; 70. estruct.weight = mgraph.edges[i][j]; 71. eArray.add(estruct); 72. } 73. } 74. } 75. } 76. //用java类库提供方法排序 77. Collections.sort(eArray); 78. } 79. 80. //查找连线顶点的尾部下标 81. public int find(int[] p,int f) 82. { 83. while(p[f] != 0) 84. f = p[f]; 85. return f; 86. } 87. 88. public void Kruskal(MGraph mgraph) 89. { 90. int i, n, m; 91. //parent数组用于判断数组边集是否形成环路 92. int[] parent = new int[eArray.size()]; 93. //初始化数组为零 94. for(i = 0; i < eArray.size(); i++) 95. parent[i] = 0; 96. //循环生成最小生成树,最小生成树的边数为图的(顶点数 - 1) 97. for(i = 0; i < mgraph.n - 1; i++) 98. { 99. n = find(parent, eArray.get(i).begin); 100. m = find(parent,eArray.get(i).end); 101. //如果n不等于m说明此边与现有生成树没有形成环路 102. if(n != m) 103. { 104. //将此边的表尾节点放入下标为起点的parent中 105. //表明此顶点已在生成树集合中 106. parent[n] = m; 107. System.out.println(eArray.get(i).begin + "," + eArray.get(i).end + " 权:" + eArray.get(i).weight); 108. } 109. } 110. } 111.}
/** 02. * 测试代码 03. * 生成邻接矩阵->prim->kruskal 04. * @author 小宇 05. * 06. */ 07. 08.public class Test 09.{ 10. public static void main(String[] args) 11. { 12. MGraph mgraph = new MGraph(); 13. 14. int[][] array = new int[6][6]; 15. for(int i = 0;i < 6; i++) 16. for(int j = 0;j < 6; j++) 17. array[i][j] = mgraph.NULL; 18. array[0][1] = 6; 19. array[1][0] = 6; 20. array[0][3] = 5; 21. array[3][0] = 5; 22. array[0][2] = 1; 23. array[2][0] = 1; 24. array[1][2] = 5; 25. array[2][1] = 5; 26. array[2][3] = 5; 27. array[3][2] = 5; 28. array[1][4] = 3; 29. array[4][1] = 3; 30. array[4][2] = 6; 31. array[2][4] = 6; 32. array[2][5] = 4; 33. array[5][2] = 4; 34. array[4][5] = 6; 35. array[5][4] = 6; 36. array[3][5] = 2; 37. array[5][3] = 2; 38. 39. 40. CreateGraph myGraph = new CreateGraph(); 41. 42. System.out.println("创建邻接矩阵:"); 43. myGraph.createMat(mgraph,array, 6); 44. myGraph.DispMat(mgraph); 45. 46. System.out.println("Prim算法生成最小生成树:"); 47. MinimalSpanningTree mst = new MinimalSpanningTree(); 48. mst.Prim(mgraph, 0); 49. 50. mst.getEStruct(mgraph); 51. mst.Kruskal(mgraph); 52. } 53.}