图 prim最小生成树算法

186 阅读1分钟

prim最小生成树算法

  • 在一个无向图中,获取一个可以连通的且权重和最小的图,可以连通指每个节点都被连接

image.png

  • prim算法从任意点开始,选择该点最小权重的边,然后从最小的边开始,继续选择最小的边,已遍历过的边不能再选择,如果该条线路已不能再选择,则从已遍历过的边里面,选择权重最小且有一端节点没有在之前最小边的路径上的,从该边开始重复上述过程
    • 如上图:A开始,遍历AB、AC、AD,选择AC,然后从C开始,遍历CA、CB、CD、CE、CF,选择CF,
    • 从F开始,遍历FE、FC、FD,选择FD,从D开始没有能够选择的边
    • 在已遍历过的边中,只有CB的权重最小,且B未在之前最小边的路径上,所以选择CB
    • 从B开始,遍历BA、BC、BE,选择BE
    • 最终的最小生成图为:AC、CF、FD、CB、BE
function prime(graph) {
  let set = new Set();
  let edgesArr = [];
  let result = [];
  //这个循环是为了如果是各自不连通的图,获取各个部分的最小生成树
  graph.nodes.values().forEach((node) => {
    if (!set.has(node)) {
      set.add(node);
    }
    //从任意一个节点开始,获取其所有的边
    edgesArr.push(...node.edges);
    //对该节点的边进行排序(逆序),方便取最小权重的边
    edgesArr.sort((a, b) => b.priority - a.priority);
    while (edgesArr.length) {
      let edge = edgesArr.pop();
      let toNode = edge.to;
      if (!set.has(toNode)) {
        set.add(toNode);
        result.add(edge);
        edgesArr.push(...toNode.edges);
        //对该节点的边进行排序(逆序),方便取最小权重的边
        edgesArr.sort((a, b) => b.priority - a.priority);
      }
    }
  });
}