克鲁斯卡尔算法//加边法
1:选择最短的边进行连接(此处的连接是连接最短边两端的点)
2:要保证连接的两端至少一个点是新的点
3:或者这个边将是两个部分进行连接(可以将已经连接的边看做是一个小部落,可以将两个小部落连接为一个大部落)
4:重复1-3的步骤直到所有的点都连接起来
如上图进行加边法
最短的边 4 也就是AB两点 符合步骤1 将两点连接
第二短的边 5 也就是CD两点 符合步骤1 将两点连接
第三短的边 6 也就是BD两点 符合步骤3 将两点连接
第四短的边 7 也就是 DE 两点 符合步骤2 将两点连接
let max = 999999;let pointSet = []; //储存点let distance = [[0, 4, 7, max, max],[4, 0, 8, 6, max],[7, 8, 0, 5, max],[max, 6, 5, 0, 7],[max, max, max, 7, 0]] // 将图的信息储存下来class Node {constructor(value) {this.value = value;this.neighbor = [];}}let a = new Node('A');let b = new Node('B');let c = new Node('C');let d = new Node('D');let e = new Node('E');pointSet.push(a)pointSet.push(b)pointSet.push(c)pointSet.push(d)pointSet.push(e)/*** 是否可以连接* @param {*} firstMember 第一个部落* @param {*} secondMember 第二个部落* @param {*} tribeArr 所有的大部落 距离最近的两个部落可以合并成一个大部落,最后所有的部落合成一个部落* @returns*/function isLink(firstMember, secondMember, tribeArr) {let beforePoin = null;let endPoin = null;// 查看所属部落// 当俩个都不属于任何部落进行连接// 当其中一个有部落,另一个没可以进行连接// 当为一个部落不能进行接连// 当两个为同一个部落的话,无法进行连接for (let i = 0; i < tribeArr.length; i++) {if (tribeArr[i].indexOf(firstMember) > -1) {beforePoin = tribeArr[i]}if (tribeArr[i].indexOf(secondMember) > -1) {endPoin = tribeArr[i]}}if (beforePoin!=null && endPoin != null&& beforePoin == endPoin) {return false;}return true;}/*** 将线两个端连接起来* @param {*} firstMember 第一个部落* @param {*} secondMember 第二个部落* @param {*} tribeArr 所有的大部落 距离最近的两个部落可以合并成一个大部落,最后所有的部落合成一个部落*/function link(firstMember, secondMember, tribeArr) {let beforePoin = null;let endPoin = null;// 查看所属部落// 当俩个都不属于任何部落进行连接// 当其中一个有部落,另一个没可以进行连接// 当两个都有部落且部落不相同时可进行连接// 当为一个部落不能进行接连for (let i = 0; i < tribeArr.length; i++) {if (tribeArr[i].indexOf(firstMember) > -1) {beforePoin = tribeArr[i]}if (tribeArr[i].indexOf(secondMember) > -1) {endPoin = tribeArr[i]}}if (beforePoin == null && endPoin == null) {//当俩个都不属于任何部落 创建一个部落 并将其记录在部落数组中let tribe = []tribe.push(firstMember)tribe.push(secondMember)tribeArr.push(tribe)} else if (beforePoin != null && endPoin == null) {// 当前一个有部落,后一个没部落,将后一个纳入部落beforePoin.push(endPoin)} else if (beforePoin == null && endPoin != null) {// 当后一个有部落,前一个没部落,将第一个纳入部落endPoin.push(beforePoin)} else if (beforePoin != null && endPoin != null && beforePoin != endPoin) {// 当俩个都有部落且部落不一样,将两个部落合并成一个部落let newTribe = beforePoin.concat(endPoin)let index = tribeArr.indexOf(endPoin)tribeArr.splice(index, 1)index = tribeArr.indexOf(beforePoin)tribeArr.splice(index, 1)tribeArr.push(newTribe)}firstMember.neighbor.push(secondMember)secondMember.neighbor.push(firstMember)}/*** 加边法* @param {*} pointSet 所有点的集合* @param {*} distance 所有线的集合*/function kruskal(pointSet, distance) {let tribeArr = []while (true) {let minDistance = max;let begin = null;let end = null;let nowValue = null;for (let i = 0; i < distance.length; i++) {for (let j = 0; j < distance[i].length; j++) {nowValue = distance[i][j]let firstMember = pointSet[i]let secondMember = pointSet[j]if (nowValue > 0 && nowValue < minDistance && isLink(firstMember, secondMember, tribeArr)) {minDistance = nowValue;begin = firstMember;end = secondMember;}}}link(begin, end, tribeArr)if (tribeArr.length == 1 && tribeArr[0].length == pointSet.length) {break;}}}kruskal(pointSet, distance)console.log(pointSet)

