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

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


微信截图_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('无环');

    }

附原文链接:原文链接

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、centos7下使用tomcat安装jenkins可以参考文章:https://blog.csdn.net/q...
  • 目录 如何遍历数组 如何遍历对象 http浏览器缓存机制 304状态码 500状态码具体场景 DNS原理 CND原...
    Grandperhaps阅读 337评论 0 1
  • 1.brew install redis 2.查看是否安装成功 brew list 3.启动redis 方法1 b...
    sunney0阅读 967评论 0 1
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 126,129评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,115评论 0 4