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
如何判断流程图中是否存在闭环?
最新推荐文章于 2024-05-20 10:05:49 发布