📅  最后修改于: 2023-12-03 15:10:52.487000             🧑  作者: Mango
在计算机程序中,图是一种非常重要的数据结构。常见的使用场景包括网络拓扑结构、地图路径规划等领域。本文将介绍如何检查基于给定条件从数组构造的图是否包含循环。
检查一个图是否包含循环一般可以使用深度优先遍历(Depth-First Search,DFS)算法。具体思路是:
对于给定条件从数组构造的图,我们还需要进行如下处理:
以下是基于Java实现的检查方法,其中adjacent_matrix参数表示邻接矩阵,is_directed表示图是否为有向图。
public static boolean containsCycle(int[][] adjacent_matrix, boolean is_directed) {
// 标记每个节点的状态:未访问、已访问、已完成
int[] visited = new int[adjacent_matrix.length];
for (int i = 0; i < visited.length; i++) {
visited[i] = 0;
}
// 从每个未访问的节点开始进行DFS
for (int i = 0; i < visited.length; i++) {
if (visited[i] == 0) {
if (dfs(adjacent_matrix, visited, is_directed, i)) {
return true;
}
}
}
return false;
}
private static boolean dfs(int[][] adjacent_matrix, int[] visited, boolean is_directed, int current) {
// 标记当前节点为已访问
visited[current] = 1;
// 遍历当前节点的邻居节点
for (int i = 0; i < adjacent_matrix.length; i++) {
if (adjacent_matrix[current][i] == 1) {
// 如果是前向边,递归访问该节点
if (visited[i] == 0) {
if (dfs(adjacent_matrix, visited, is_directed, i)) {
return true;
}
}
// 如果是反向边,说明存在循环
else if (!is_directed && visited[i] == 1) {
return true;
}
}
}
// 标记当前节点为已完成
visited[current] = 2;
return false;
}
以下是几组测试用例,可以用于验证检查方法的正确性:
对于以下邻接矩阵,返回true表示存在循环。
int[][] adjacent_matrix = {
{0, 1, 0, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 0}
};
System.out.println(containsCycle(adjacent_matrix, true)); // true
对于以下邻接矩阵,返回false表示不存在循环。
int[][] adjacent_matrix = {
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
{0, 0, 0, 0}
};
System.out.println(containsCycle(adjacent_matrix, true)); // false
对于以下邻接矩阵,返回true表示存在循环。
int[][] adjacent_matrix = {
{0, 1, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 1, 1},
{0, 0, 0, 0, 1},
{0, 0, 0, 0, 0}
};
System.out.println(containsCycle(adjacent_matrix, false)); // true
深度优先遍历是一种常用的图遍历算法,对于检查图是否包含循环也可以使用该算法。对于基于给定条件从数组构造的图,需要将数组转换成邻接矩阵的形式,并进行前向边和反向边的判断。