image.png
加点法是以一个初始点开始的,而加边法是以最短的边开始的

克鲁斯卡尔算法//加边法

1:选择最短的边进行连接(此处的连接是连接最短边两端的点)
2:要保证连接的两端至少一个点是新的点
3:或者这个边将是两个部分进行连接(可以将已经连接的边看做是一个小部落,可以将两个小部落连接为一个大部落)
4:重复1-3的步骤直到所有的点都连接起来
如上图进行加边法
最短的边 4 也就是AB两点 符合步骤1 将两点连接
第二短的边 5 也就是CD两点 符合步骤1 将两点连接
第三短的边 6 也就是BD两点 符合步骤3 将两点连接
第四短的边 7 也就是 DE 两点 符合步骤2 将两点连接

  1. let max = 999999;
  2. let pointSet = []; //储存点
  3. let distance = [
  4. [0, 4, 7, max, max],
  5. [4, 0, 8, 6, max],
  6. [7, 8, 0, 5, max],
  7. [max, 6, 5, 0, 7],
  8. [max, max, max, 7, 0]
  9. ] // 将图的信息储存下来
  10. class Node {
  11. constructor(value) {
  12. this.value = value;
  13. this.neighbor = [];
  14. }
  15. }
  16. let a = new Node('A');
  17. let b = new Node('B');
  18. let c = new Node('C');
  19. let d = new Node('D');
  20. let e = new Node('E');
  21. pointSet.push(a)
  22. pointSet.push(b)
  23. pointSet.push(c)
  24. pointSet.push(d)
  25. pointSet.push(e)
  26. /**
  27. * 是否可以连接
  28. * @param {*} firstMember 第一个部落
  29. * @param {*} secondMember 第二个部落
  30. * @param {*} tribeArr 所有的大部落 距离最近的两个部落可以合并成一个大部落,最后所有的部落合成一个部落
  31. * @returns
  32. */
  33. function isLink(firstMember, secondMember, tribeArr) {
  34. let beforePoin = null;
  35. let endPoin = null;
  36. // 查看所属部落
  37. // 当俩个都不属于任何部落进行连接
  38. // 当其中一个有部落,另一个没可以进行连接
  39. // 当为一个部落不能进行接连
  40. // 当两个为同一个部落的话,无法进行连接
  41. for (let i = 0; i < tribeArr.length; i++) {
  42. if (tribeArr[i].indexOf(firstMember) > -1) {
  43. beforePoin = tribeArr[i]
  44. }
  45. if (tribeArr[i].indexOf(secondMember) > -1) {
  46. endPoin = tribeArr[i]
  47. }
  48. }
  49. if (beforePoin!=null && endPoin != null&& beforePoin == endPoin) {
  50. return false;
  51. }
  52. return true;
  53. }
  54. /**
  55. * 将线两个端连接起来
  56. * @param {*} firstMember 第一个部落
  57. * @param {*} secondMember 第二个部落
  58. * @param {*} tribeArr 所有的大部落 距离最近的两个部落可以合并成一个大部落,最后所有的部落合成一个部落
  59. */
  60. function link(firstMember, secondMember, tribeArr) {
  61. let beforePoin = null;
  62. let endPoin = null;
  63. // 查看所属部落
  64. // 当俩个都不属于任何部落进行连接
  65. // 当其中一个有部落,另一个没可以进行连接
  66. // 当两个都有部落且部落不相同时可进行连接
  67. // 当为一个部落不能进行接连
  68. for (let i = 0; i < tribeArr.length; i++) {
  69. if (tribeArr[i].indexOf(firstMember) > -1) {
  70. beforePoin = tribeArr[i]
  71. }
  72. if (tribeArr[i].indexOf(secondMember) > -1) {
  73. endPoin = tribeArr[i]
  74. }
  75. }
  76. if (beforePoin == null && endPoin == null) {
  77. //当俩个都不属于任何部落 创建一个部落 并将其记录在部落数组中
  78. let tribe = []
  79. tribe.push(firstMember)
  80. tribe.push(secondMember)
  81. tribeArr.push(tribe)
  82. } else if (beforePoin != null && endPoin == null) {
  83. // 当前一个有部落,后一个没部落,将后一个纳入部落
  84. beforePoin.push(endPoin)
  85. } else if (beforePoin == null && endPoin != null) {
  86. // 当后一个有部落,前一个没部落,将第一个纳入部落
  87. endPoin.push(beforePoin)
  88. } else if (beforePoin != null && endPoin != null && beforePoin != endPoin) {
  89. // 当俩个都有部落且部落不一样,将两个部落合并成一个部落
  90. let newTribe = beforePoin.concat(endPoin)
  91. let index = tribeArr.indexOf(endPoin)
  92. tribeArr.splice(index, 1)
  93. index = tribeArr.indexOf(beforePoin)
  94. tribeArr.splice(index, 1)
  95. tribeArr.push(newTribe)
  96. }
  97. firstMember.neighbor.push(secondMember)
  98. secondMember.neighbor.push(firstMember)
  99. }
  100. /**
  101. * 加边法
  102. * @param {*} pointSet 所有点的集合
  103. * @param {*} distance 所有线的集合
  104. */
  105. function kruskal(pointSet, distance) {
  106. let tribeArr = []
  107. while (true) {
  108. let minDistance = max;
  109. let begin = null;
  110. let end = null;
  111. let nowValue = null;
  112. for (let i = 0; i < distance.length; i++) {
  113. for (let j = 0; j < distance[i].length; j++) {
  114. nowValue = distance[i][j]
  115. let firstMember = pointSet[i]
  116. let secondMember = pointSet[j]
  117. if (nowValue > 0 && nowValue < minDistance && isLink(firstMember, secondMember, tribeArr)) {
  118. minDistance = nowValue;
  119. begin = firstMember;
  120. end = secondMember;
  121. }
  122. }
  123. }
  124. link(begin, end, tribeArr)
  125. if (tribeArr.length == 1 && tribeArr[0].length == pointSet.length) {
  126. break;
  127. }
  128. }
  129. }
  130. kruskal(pointSet, distance)
  131. console.log(pointSet)