当前位置:   article > 正文

克鲁斯卡尔(Kruskal)算法生成最小生成树(MST)原理及算法实现

克鲁斯卡尔(Kruskal)算法生成最小生成树(MST)原理及算法实现

一、目的

本实验旨在理解和掌握克鲁斯卡尔(Kruskal)算法的基本原理,并通过编程实现该算法,以求解给定无向加权图的最小生成树。通过本实验,能够加深对最小生成树概念的理解,并提升编程能力。

二、原理

克鲁斯卡尔算法是一种求解最小生成树的贪心算法。其基本原理是:首先,将所有边按照权重从小到大进行排序;然后,从权重最小的边开始,如果这条边连接的两个顶点不在同一个集合中(即不构成环),则将其加入最小生成树中,并将这两个顶点所在的集合合并;重复这个过程,直到选择了n-1条边(n为顶点的数量)或者所有边都已被考虑。

三、步骤

  • 首先定义了一个Edge类,表示图中的边。它包含源节点(src)、目标节点(dest)和权重(weight)三个属性,并实现了Comparable接口,以便对边进行排序。
  • 然后定义了一个KruskalMST类,其中包含了主函数main。在主函数中,首先定义了顶点数目V为4,然后创建了一个包含5条边的数组edges。每条边由源节点、目标节点和权重组成。
  • 接下来,使用Arrays.sort()方法对边数组进行排序,按照权重从小到大的顺序排列。
  • 创建一个UnionFind对象,用于实现并查集数据结构。并查集是一种用于处理不相交集合的数据结构,可以高效地合并和查找集合。
  • 初始化一个变量mstWeight,用于计算最小生成树的总权重。
  • 遍历排序后的边数组,对于每条边,通过并查集判断两个顶点是否属于同一棵树。如果不属于同一棵树,则将这条边添加到最小生成树中,并更新总权重。同时输出包含该边的相关信息。
  • 最后输出最小生成树的总权重。
  • UnionFind类是并查集的实现,包括了查找操作和联合操作。查找操作使用了路径压缩技术,以提高后续查找的效率。联合操作根据树的排名进行合并,以保持树的高度尽可能小。

四、算法实现

  1. package com.lwtstu5.practice;
  2. import java.util.Arrays;
  3. class Edge implements Comparable<Edge> {
  4. int src, dest, weight;
  5. // Edge类的构造函数
  6. public Edge(int src, int dest, int weight) {
  7. this.src = src;
  8. this.dest = dest;
  9. this.weight = weight;
  10. }
  11. // 按照权重对Edge对象进行排序
  12. public int compareTo(Edge compareEdge) {
  13. return this.weight - compareEdge.weight;
  14. }
  15. }
  16. class KruskalMST {
  17. // 主函数
  18. public static void main(String[] args) {
  19. int V = 4; // 顶点数目
  20. Edge[] edges = new Edge[] {
  21. new Edge(0, 1, 10),
  22. new Edge(0, 2, 6),
  23. new Edge(0, 3, 5),
  24. new Edge(1, 3, 15),
  25. new Edge(2, 3, 4)
  26. };
  27. int E = edges.length;
  28. Arrays.sort(edges); // 按权重对边进行排序
  29. UnionFind unionFind = new UnionFind(V);
  30. long mstWeight = 0; // 用于计算MST的总权重
  31. // 遍历所有边,按照权重从小到大添加到MST
  32. for (Edge edge : edges) {
  33. int x = unionFind.find(edge.src);
  34. int y = unionFind.find(edge.dest);
  35. // 如果边的两个顶点不属于同一树(即它们的根不同),可以添加到MST中
  36. if (x != y) {
  37. unionFind.union(x, y);
  38. mstWeight += edge.weight; // 更新MST的总权重
  39. System.out.println("包含边 " + edge.src + "-" + edge.dest + " 权重: " + edge.weight);
  40. }
  41. }
  42. System.out.println("MST的总权重是: " + mstWeight);
  43. }
  44. // 并查集的实现
  45. static class UnionFind {
  46. private int[] parent;
  47. private int[] rank;
  48. public UnionFind(int V) {
  49. parent = new int[V];
  50. rank = new int[V];
  51. for (int i = 0; i < V; i++) {
  52. parent[i] = i;
  53. rank[i] = 0;
  54. }
  55. }
  56. // 查找操作,带路径压缩
  57. public int find(int i) {
  58. if (parent[i] != i) {
  59. parent[i] = find(parent[i]); // 路径压缩
  60. }
  61. return parent[i];
  62. }
  63. // 联合操作
  64. public void union(int x, int y) {
  65. int xRoot = find(x);
  66. int yRoot = find(y);
  67. // 根据排名进行合并
  68. if (rank[xRoot] > rank[yRoot]) {
  69. parent[yRoot] = xRoot;
  70. } else if (rank[xRoot] < rank[yRoot]) {
  71. parent[xRoot] = yRoot;
  72. } else {
  73. parent[yRoot] = xRoot;
  74. rank[xRoot] += 1;
  75. }
  76. }
  77. }
  78. }

五、结果与分析

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/616590
推荐阅读
相关标签
  

闽ICP备14008679号