美文网首页
记一次有向图闭环验证(js)

记一次有向图闭环验证(js)

作者: 德德de_前端攻城狮 | 来源:发表于2021-05-31 14:13 被阅读0次

    需求:流程图,连接节点的同时验证是否存在闭环


    微信截图_20210531140501.png
    function DFS(i) {
            console.log('正在访问结点' + nodes[i]);
            //结点i变为访问过的状态
            visited[nodes[i]] = 1;
            for (let j = 0; j < nodes.length; j++) {
                //如果当前结点有指向的结点
                if (graph[nodes[i]][nodes[j]] != 0) {
                    //并且已经被访问过
                    if (visited[nodes[j]] == 1) {
                        isDAG = false; //有环
                        break;
                    } else if (visited[nodes[j]] == -1) {
                        //当前结点后边的结点都被访问过,直接跳至下一个结点
                        continue;
                    } else {
                        DFS(j); //否则递归访问
                    }
                }
            }
            //遍历过所有相连的结点后,把本节点标记为-1
            visited[nodes[i]] = -1;
        }
        //创建图,以邻接矩阵表示
        function create(nodes, edges) {
            for (let i = 0; i < nodes.length; i++) {
                const pre = nodes[i];
                graph[pre] = {};
                for (let j = 0; j < nodes.length; j++) {
                    const next = nodes[j];
                    graph[pre][next] = 0;
                }
            }
            for (let k = 0; k < edges.length; k++) {
                const edge = edges[k];
                graph[edge.source][edge.target] = 1;
            }
            //初始化color数组为0,表示一开始所有顶点都未被访问过
            for (let i = 0; i < nodes.length; i++) {
                visited[nodes[i]] = 0;
            }
        }
        //邻接矩阵
        const graph = {};
        //结点个数和边的个数
        //标记矩阵,0为当前结点未访问,1为访问过,-1表示当前结点后边的结点都被访问过。
        const visited = {};
        //是否是DAG(有向无环图)
        let isDAG = true;
        // 获取所有的节点
        const edges = [
            {
                source: 'node2',
                target: 'node3'
            },
            {
                source: 'node1',
                target: 'node2'
            },
            {
                source: 'node3',
                target: 'node1'
            },
            {
                source: 'node4',
                target: 'node2'
            },
            {
                source: 'node4',
                target: 'node3'
            }       
        ];
        const nodes = [];
        edges.forEach(e => {
            const { source, target } = e;
            if (!nodes.includes(source)) {
                nodes.push(source);
            }
            if (!nodes.includes(target)) {
                nodes.push(target);
            }
        });
        create(nodes, edges);
        //保证每个节点都遍历到,排除有的结点没有边的情况
        for (let i = 0; i < nodes.length; i++) {
            //该结点后边的结点都被访问过了,跳过它
            if (visited[nodes[i]] == -1) {
                continue;
            }
            DFS(i);
            if (!isDAG) {
                console.log('有环');
                break;
            }
        }
        if (isDAG) {
            console.log('无环');
    
        }
    

    附原文链接:原文链接

    相关文章

      网友评论

          本文标题:记一次有向图闭环验证(js)

          本文链接:https://www.haomeiwen.com/subject/kchbsltx.html