图 指定节点求到其他节点的最短距离

241 阅读2分钟

题目

image.png 指定任意一个节点,求该节点到其他节点的最短距离

  • 设置两个集合,一个集合distanceMap用来记录到其他点的距离,一个集合selectedNode用来记录已经找到的到某个点的最短距离的点,
  • 假定指定A点,求A到其它点的最短距离
  • 首先设置distanceMap中A到A到距离为0,A能直接到的点为DCB,设置distanceMap的距离分别为0,15,3
  • 将A放入selectedNode中,因为A到A到距离确定为最小,从distanceMap中拿到非已确定最小距离节点的其他节点,拿到B,最小距离为3,
  • 从最小节点B开始,设置distancMap中从B出发到其他节点的距离(即A-B后,以B为起始点),B到A为6(A-B-A),C的距离为5(A-B-C),...,B到E为203,因为目前确定A-B的最短路径就为3,所以B放入selecttedNode中
  • 从distanceMap中拿到非已确定最小距离节点的其他节点,拿到C,重复上面逻辑后,继续取最小节点为E,路径为A-B-C-E,为19
  • 直到无法找到到其他节点的最小距离节点为止,期间如果遇到该节点到另一个节点的路径距离小于另一个节点历史记录到值,就更新
function getMinPath(node) {
  //记录指定节点到其他节点的距离
  let distanceMap = new Map();
  //记录已经是最短距离的节点
  let selectedNode = new Set();
  //将自身加入
  distanceMap.put(node, 0);
  //初识时最小节点就返回自身
  let minNode = getMinNode(distanceMap, selectedNode);

  while (minNode) {
    let distance = distanceMap.get(minNode);
    //遍历最小节点的所有边
    minNode.edges.forEach((edge) => {
      //获取边指向的节点
      let toNode = edge.to;
      //针对初次遇到的节点,设置距离为当前最小节点距离指定节点的距离+当前最小节点到该节点的距离
      if (!distanceMap.get(toNode)) {
        distanceMap.put(toNode, distance + toNode.weight);
      }
      //对于已经记录的节点,比较记录的距离和当前最小距离节点到该节点的距离,取最小值
      distanceMap.set(
        toNode,
        Math.min(distance.get(toNode), distance + toNode.weight)
      );
    });
    //加入最小节点
    selectedNode.add(minNode);
    //获取下一个未加入记录的最小距离节点,因为是指定节点到其他节点,所以每次要从最小节点出发
    minNode = getMinNode(distanceMap, selectedNode);
  }

  return distanceMap;
}
//从未确定节点中
function getMinNode(distanceMap, selectedNode) {
  let minNode,
    minDistance = Number.MAX_VALUE;
  //遍历记录的节点,查找没有确定的最小距离节点中的最小距离节点
  distanceMap.keys().forEach((key) => {
    if (!selectedNode.containes(key) && minDistance > distanceMap.get(key)) {
      minNode = key;
      minDistance = distanceMap.get(key);
    }
  });
  return minNode;
}