Эта идея жесткого кодирования может показаться хорошим началом, но, как вы заметили, для решения подобных проблем потребуется принципиально иная стратегия.
Обнаружение цикла может быть выполнено наивно поиск в глубину , начиная с каждого узла. Перед началом создайте пустой набор для отслеживания посещенных узлов. Когда вы посещаете узел, сначала посмотрите его в наборе. Если он уже там, вы нашли цикл; в противном случае отметьте посещение и выполните поиск всех соседних соседей. Если вы не нашли циклов для узла, отметьте его как непосещенный перед выходом из его кадра вызова, чтобы избежать ложных срабатываний, если к нему имеется несколько путей.
Вы можете сделать это итеративно, используя стек и все oop. вставьте стек, чтобы посетить узел, и поместите его sh его соседей в стек. Фундаментальный подход тот же, что вы используете поиск по посещенному набору для обнаружения циклов.
Если у вас есть базовая реализация c, вы можете от sh до оптимизировать .
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
bool is_cyclic_(int curr, int n, bool **graph, bool **visited) {
if ((*visited)[curr]) {
return true;
}
(*visited)[curr] = true;
for (int i = 0; i < n; i++) {
if (graph[curr][i] && is_cyclic_(i, n, graph, visited)) {
return true;
}
}
(*visited)[curr] = false;
return false;
}
bool is_cyclic(int n, bool **graph) {
bool *visited = calloc(n, sizeof(*visited));
for (int i = 0; i < n; i++) {
if (is_cyclic_(i, n, graph, &visited)) {
free(visited);
return true;
}
}
free(visited);
return false;
}
int main() {
int n = 5;
bool graph[][5] = {
{0,0,0,1,0},
{0,0,0,0,0},
{0,0,0,0,1},
{0,0,1,0,0},
{1,0,0,0,0},
};
bool **pgraph = malloc(sizeof(*pgraph) * n);
for (int i = 0; i < n; i++) {
pgraph[i] = malloc(sizeof(pgraph[i]) * n);
for (int j = 0; j < n; j++) {
pgraph[i][j] = graph[i][j];
}
}
printf("%d\n", is_cyclic(n, pgraph));
for (int i = 0; i < n; i++) {
free(pgraph[i]);
}
free(pgraph);
return 0;
}