如何判断流程图中是否存在闭环?

const validate = (edges: any) => {
    if (!edges?.length) return
    // 邻接矩阵
    let graph: any = {};
    // 标记矩阵,0为当前结点未访问,1为访问过,-1表示当前结点后边的结点都被访问过。
    let visited: any = {};
    // 是否是闭环,默认否
    let flag: boolean = false;
    // 获取所有的节点
    let nodes: string[] = [];
    const create = (nodes: string[]) => {
        nodes?.forEach((nodeItem: string) => {
            graph[nodeItem] = {}
            nodes?.forEach((nodeChildItem: string) => {
                graph[nodeItem][nodeChildItem] = 0
            })
        })
        edges?.forEach((edgeItem: any) => {
            graph[edgeItem.from][edgeItem.to] = 1
        })
        // 初始化数组为0,表示一开始所有顶点都未被访问过
        nodes?.forEach((item: string) => {
            visited[item] = 0
        })
    };
    const DFS = (pNode: string) => {
        // 当前结点变为访问过的状态
        visited[pNode] = 1
        nodes?.forEach((nodeItem: string) => {
            // 如果当前结点有指向的结点
            if (0 !== graph[pNode][nodeItem]) {
                // 并且已经被访问过
                if (1 === visited[nodeItem]) {
                    // 闭环
                    closedLoop = true
                    return;
                } else if (-1 === visited[nodeItem]) {
                    // 当前结点后边的结点都被访问过,直接跳至下一个结点
                    return;
                } else {
                    // 否则递归访问
                    DFS(nodeItem)
                }
            }
        });
        // 遍历过所有相连的结点后,把本节点标记为-1
        visited[pNode] = -1
    }
    edges?.forEach((linkItem: any) => {
        const { from, to } = linkItem
        if (!nodes.includes(from)) {
            nodes.push(from)
        }
        if (!nodes.includes(to)) {
            nodes.push(to)
        }
    })
    create(nodes)
    nodes?.forEach((item: string) => {
        DFS(item)
    })

    return flag
};


const links = [
    { from: '111', to: '222' },
    { from: '222', to: '111' },
];

console.log(validate(links)); // true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值