Java语言怎么进行一次扫描实现对于有向图是否存在环进行判断,编写成函数,能不能不用递归?不要递归的写法是什么
如图
import java.util.*;
public class DirectedGraph {
private int V;
private List<List<Integer>> adjList;
public DirectedGraph(int vertices) {
V = vertices;
adjList = new ArrayList<>(V);
for (int i = 0; i < V; i++) {
adjList.add(new ArrayList<>());
}
}
public void addEdge(int src, int dest) {
adjList.get(src).add(dest);
}
public boolean isCyclic() {
boolean[] visited = new boolean[V];
boolean[] stack = new boolean[V];
Stack<Integer> stackDFS = new Stack<>();
for (int i = 0; i < V; i++) {
if (isCyclicUtil(i, visited, stack, stackDFS)) {
return true;
}
}
return false;
}
private boolean isCyclicUtil(int vertex, boolean[] visited, boolean[] stack, Stack<Integer> stackDFS) {
visited[vertex] = true;
stack[vertex] = true;
stackDFS.push(vertex);
List<Integer> neighbors = adjList.get(vertex);
for (int neighbor : neighbors) {
if (!visited[neighbor]) {
if (isCyclicUtil(neighbor, visited, stack, stackDFS)) {
return true;
}
} else if (stack[neighbor]) {
// 如果某个邻居已经被访问过且存在于递归栈中,则表示存在环
return true;
}
}
// 将当前节点出栈,并将对应的标记置为false
stack[vertex] = false;
stackDFS.pop();
return false;
}
public static void main(String[] args) {
DirectedGraph graph = new DirectedGraph(4);
graph.addEdge(0, 1);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
if (graph.isCyclic()) {
System.out.println("图中包含一个循环");
} else {
System.out.println("图中不包含一个循环");
}
}
}
思路 : 使用深度优先搜索(DFS)算法来判断有向图是否存在环
你看看这个:https://blog.csdn.net/weixin_68320784/article/details/123989512
不知道你这个问题是否已经解决, 如果还没有解决的话:解决方案:
我的解决方案基于深度优先搜索(DFS)算法,使用一个栈来存储图的遍历路径,以及一个visited数组来记录已经访问过的节点。
以下是使用Java语言编写的函数来判断有向图是否存在环:
import java.util.*;
public class GraphCycleDetection {
private int V; // 图的顶点数
private List<List<Integer>> adj; // 邻接表表示图
public GraphCycleDetection(int V) {
this.V = V;
adj = new ArrayList<>(V);
for (int i = 0; i < V; ++i)
adj.add(new LinkedList<>());
}
public void addEdge(int v, int w) {
adj.get(v).add(w);
}
public boolean isCyclic() {
boolean[] visited = new boolean[V]; // 记录节点是否被访问过
boolean[] onStack = new boolean[V]; // 记录节点是否在栈中
for (int i = 0; i < V; ++i) {
if (dfs(i, visited, onStack))
return true;
}
return false;
}
private boolean dfs(int v, boolean[] visited, boolean[] onStack) {
visited[v] = true;
onStack[v] = true;
for (int neighbor : adj.get(v)) {
if (!visited[neighbor]) {
if (dfs(neighbor, visited, onStack))
return true;
} else if (onStack[neighbor]) {
return true;
}
}
onStack[v] = false;
return false;
}
public static void main(String[] args) {
GraphCycleDetection graph = new GraphCycleDetection(4);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
graph.addEdge(3, 3);
if (graph.isCyclic())
System.out.println("图中存在环");
else
System.out.println("图中不存在环");
}
}
这段代码创建了一个GraphCycleDetection
类来表示有向图。addEdge
函数用于添加边,isCyclic
函数用于判断图中是否存在环。dfs
函数用于进行深度优先搜索,通过visited
和onStack
数组来记录节点的访问状态和在栈中的状态。
在main
函数中,我创建了一个示例图来测试代码。你可以根据需要修改图的顶点数和边的连接关系。
运行这段代码,如果图中存在环,则会打印出"图中存在环";如果图中不存在环,则会打印出"图中不存在环"。
希望这个解决方案对你有帮助。如果有任何问题,请随时提问。