记一次有向图闭环验证(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('无环');

    }

附原文链接:原文链接

你可能感兴趣的:(记一次有向图闭环验证(js))