假设有向图采用邻接表存储。设计一个算法,判断有向图中是否存在回路。C语言完整代码
时间: 2024-12-24 09:33:52 浏览: 6
在C语言中,我们可以使用深度优先搜索(Depth-First Search,DFS)或者拓扑排序(Topological Sort)来检测有向图中是否存在回路。这里我们选择使用DFS,因为DFS的一个特性是在找到环的时候会进入无限循环,这可以作为是否有回路的标志。
下面是DFS实现的基本步骤:
1. 初始化:对于每个节点,设其访问状态为未访问,并创建一个布尔数组用于标记已访问过的节点。
2. 遍历:从任意一个节点开始,递归地访问它的邻居。如果邻居已被访问过并且它是一个前驱节点,则说明存在环;如果没有遍历完所有节点而当前节点的状态仍然是访问中,则可能存在环。
3. 回溯:访问结束后,回到上一个节点继续检查其他未访问的邻居。
以下是C语言的简单实现:
```c
#include <stdbool.h>
// 假设adj_list[]是一个邻接表结构体数组,表示有向图
void detectCycle(int src, bool* visited, int* adj_list[], int n) {
visited[src] = true; // 标记为已访问
for (int i = 0; i < adj_list[src].size; i++) { // 遍历邻居
int neighbor = adj_list[src][i];
if (!visited[neighbor]) {
detectCycle(neighbor, visited, adj_list, n); // 递归访问
} else if (visited[neighbor] && neighbor != src) { // 如果遇到已访问的非源节点,则有环
printf("A cycle is detected in the graph.\n");
return;
}
}
}
bool hasCycle(int adj_list[], int n) {
bool* visited = malloc(sizeof(bool) * n);
if (!visited) {
perror("Memory allocation failed.");
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; i++) {
visited[i] = false;
}
for (int i = 0; i < n; i++) {
if (!visited[i]) {
detectCycle(i, visited, adj_list, n);
break; // 只需检查一次即可,因为一旦发现环就会立即返回
}
}
free(visited);
return !hasCycleDetected; // hasCycleDetected会被设置为true表示有环
}
阅读全文