From 12e74e35209d9016cf52fed525e94a9240bc1bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?yinjinlu-pc=5C=E5=B0=B9=E9=87=91=E8=B7=AF?= <411641505@qq.com> Date: Wed, 15 Jan 2025 09:48:34 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=A9=E6=96=99=E9=9C=80=E6=B1=82=E6=9C=89?= =?UTF-8?q?=E5=90=91=E5=9B=BE=E7=8E=AF=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ktg/common/utils/MapCircleUtils.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ktg-common/src/main/java/com/ktg/common/utils/MapCircleUtils.java diff --git a/ktg-common/src/main/java/com/ktg/common/utils/MapCircleUtils.java b/ktg-common/src/main/java/com/ktg/common/utils/MapCircleUtils.java new file mode 100644 index 0000000..b0ac05f --- /dev/null +++ b/ktg-common/src/main/java/com/ktg/common/utils/MapCircleUtils.java @@ -0,0 +1,72 @@ +package com.ktg.common.utils; + +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @author yinjinlu + * @description 物料BOM环形依赖关系有向图检测 + * @date 2024/12/18 + */ +@Service +public class MapCircleUtils { + + private Map> adj; // 邻接表 + + private MapCircleUtils() { + this.adj = new HashMap<>(); + } + + + public void clear() { + adj.clear(); + } + + public void addEdge(int v, int w) { + adj.computeIfAbsent(v, k -> new ArrayList<>()).add(w); + adj.computeIfAbsent(w, k -> new ArrayList<>()); + } + + + public int getVertices() { + return adj.size(); + } + + private boolean isCircleUtil(Integer v, boolean[] visited, boolean[] onStack) { + if (visited[v]) { + return true; // 已经访问过,说明有环 + } + + if (onStack[v]) { + return false; // 已访问过且不在递归栈中 + } + + visited[v] = true; + onStack[v] = true; + + for (Integer w : adj.getOrDefault(v, Collections.emptyList())) { + if (isCircleUtil(w, visited, onStack)) { + return true; + } + } + + onStack[v] = false; + return false; + } + + private int getMaxVertextIndex(){ + return adj.isEmpty() ? -1 : Collections.max(adj.keySet()); + } + + public boolean hasCircle() { + boolean[] visited = new boolean[getMaxVertextIndex() + 1]; + boolean[] onStack = new boolean[getMaxVertextIndex() + 1]; + for ( int vertext: adj.keySet()) { + if (!visited[vertext] && isCircleUtil(vertext, visited, onStack)) { + return true; + } + } + return false; + } +}