再看最后一眼青春的星空

灿烂火光就像盛夏的烟火

欢送挣扎万年文明的巅峰

我们啊

将变星辰永远飘在黑暗宇宙

这个男人来自三体

Tirion

导航

roc-charts 开发笔记:查找图中两点的所有路径

  1. 把图看成以起点为根节点的树状图
  2. 使用深度遍历算法遍历路径
  3. 遍历到节点为目标节点时,保存这条路径
find2PointsPath(sourceId, targetId) {
    const { nodesKV } = this.chart.getStore();  // 节点集合
    let pathArr = [];  // 保存找到的所有路径

    /**
    *
    * @param {string} sourceId 当前节点 id,每次递归会改变
    * @param {string} targetId 目标节点 id
    * @param {array} pathNodes 当前查找路径的所有节点 id 
    */
    const findPath = (sourceId, targetId, pathNodes = []) => {
        pathNodes = [...pathNodes];  // 存储当前路径的节点 id。拷贝一下,避免引用传递导致递归调用时相互影响。
        pathNodes.push(sourceId);
        // 找到终点,保存路径退出
        if (sourceId === targetId) {
            pathArr.push(pathNodes);
            return;
        }

        // 取出当前节点
        const node = nodesKV[sourceId];
        // 通过当前节点取出相邻的节点
        const neighborNodes = { ...gof(node, {})('childrenKV')(), ...gof(node, {})('parentsKV')() };

        // 遍历相邻节点继续查找
        for (let id in neighborNodes) {
            // 没在当前查找路径中的才递归继续查找,避免图中的环导致死循环
            // 比如 A-B, A-C, B-C 这样的关系,我们从 A 找到 B,从 B 找到 C,pathNodes 中有 [A, B],然后从 C 找,A 和 B 都是 C 的相邻节点,如果不排除 pathNodes 中的节点必然陷入死循环
            if (!pathNodes.includes(id)) {
                findPath(id, targetId, pathNodes);
            }
        }
    };
    // 开始查找
    findPath(sourceId, targetId);

    // 路径长度由短到长排序
    pathArr.sort((path1, path2) => {
        return path1.length - path2.length;
    });

    return pathArr;
}

posted on 2018-09-05 16:42  Tirion  阅读(550)  评论(0编辑  收藏  举报

The Man from 3body