JS使用呆板的算法和Kruskal算法实现最小生成的树

  

之前都是看的书,大部分也是c++的实现,但是搞前端不能忘了JS啊,所以JS实现一遍这两个经典的最小生成树算法。

  

<强>一、权重图和最小生成树
  

  

权重图:图的边带权重

  

最小生成树:在连通图的所有生成树中,所有边的权重和最小的生成树

  

本文使用的图如下:

  

 JS使用呆板的算法和Kruskal算法实现最小生成树

  

它的最小生成树如下:

  

 JS使用呆板的算法和Kruskal算法实现最小生成树

  

<强>二,邻接矩阵
  

  

邻接矩阵:用来表示图的矩阵就是邻接矩阵,其中下标表示顶点,矩阵中的值表示边的权重(或者有无边,方向等)。

  

本文在构建邻接矩阵时,默认表示两个节点之间没有边,表示当前节点没有自环。

  

代码如下:

     /* *   *邻接矩阵   *值为顶点与顶点之间边的权值,0表示无自环,一个大数表示无边(比如10000)   * */const MAX_INTEGER=Number.MAX_SAFE_INTEGER;//没有的边   const MIN_INTEGER=Number.MIN_SAFE_INTEGER;//没有自环      const矩阵=[   [MIN_INTEGER 9 2 MAX_INTEGER 6),   MAX_INTEGER MIN_INTEGER[9日,3日,MAX_INTEGER),   (2、3、MIN_INTEGER 5 MAX_INTEGER),   [MAX_INTEGER MAX_INTEGER 5, MIN_INTEGER, 1],   (6 MAX_INTEGER MAX_INTEGER 1 MIN_INTEGER]   );      

这个邻接矩阵表示的图如下:

  

<强>三,边的表示
  

  

一个边具有权重,起点,重点三个属性,所以可以创建一个类(对象),实现如下:

     /* *   *边对象   * */函数边缘(开始、结束、重量){   这一点。开始=开始;   这一点。结束=结束;   这一点。重量=重量;   }      Edge.prototype。getBegin=function () {   返回this.begin;   };   Edge.prototype。getEnd=function () {   返回this.end;   };   Edge.prototype。getWeight=function () {   返回this.weight;   };      {/*类边缘   构造函数(开始、结束、重量){   这一点。开始=开始;   这一点。结束=结束;   这一点。重量=重量;   }   getBegin () {   返回this.begin;   }   getEnd () {   返回this.end;   }   getWeight () {   返回this.weight;   }   }*/      

, PS: JS这门语言没有私有变量的说法,这里写得到方法纯粹是模拟一下私有变量。可以不用这么写,可以直接通过属性访问到属性值。

  

<强>四,拘谨的算法
  

  

将这个算法的文章数不胜数,这里就不细说了。

  

其大体思路就是:以某顶点为起点,逐步找各顶点上最小权值的相邻边构建最小生成树,同时其邻接点纳入生成树的顶点中,只要保证顶点不重复添加即可。

  

实现代码如下:

     /* *   *拘谨的算法   *以某顶点为起点,逐步找各顶点上最小权值的边构建最小生成树,同时其邻接点纳入生成树的顶点中,只要保证顶点不重复添加即可   *使用邻接矩阵即可   *优点:适合点少边多的情况   * @param矩阵邻接矩阵   * @return数组最小生成树的边集数组   * */函数的(矩阵){=matrix.length const行,   关口=行,   结果=[],   savedNode=[0];//已选择的节点   让minVex=1,   minWeight=MAX_INTEGER;   (让我=0;我& lt;行;我+ +){   让行=savedNode[我],   edgeArr=矩阵(行);   (让j=0;j & lt;关口;j + +) {   如果(edgeArr [j] & lt;minWeight,,edgeArr [j]。==MIN_INTEGER) {   minWeight=edgeArr [j];   minVex=j;   }   }//保证所有已保存节点的相邻边都遍历到   如果(savedNode.indexOf (minVex)===1,,我===savedNode。长度- 1){   savedNode.push (minVex);   结果。推动(新边缘(行,minVex, minWeight));//重新在已加入的节点集中找权值最小的边的外部边   i=1;   minWeight=MAX_INTEGER;//已加入的边,去掉,下次就不会选这条边了   矩阵[行][minVex]=MAX_INTEGER;   矩阵[minVex](行)=MAX_INTEGER;   }   }   返回结果;   }      

<强>五,Kruskal算法
  

  

介绍这个算法的文章也很多,这里不细说。

  

其主要的思路就是:遍历所有的边,按权值从小到大排的序,每次选取当前权值最小的边,只要不构成回环,则加入生成树。

JS使用呆板的算法和Kruskal算法实现最小生成的树