Поиск цикла (DFS-краски)
Серое ребро в серую вершину = цикл: DFS трёхцветный.
1function hasCycle(graph: Map<string, string[]>): boolean {2 const WHITE = 0, GRAY = 1, BLACK = 23 const color = new Map<string, number>()4 5 function dfs(v: string): boolean {6 color.set(v, GRAY) // в текущем стеке вызовов7 for (const w of graph.get(v) ?? []) {8 const c = color.get(w) ?? WHITE9 if (c === GRAY) return true // ребро в предка = цикл!10 if (c === WHITE && dfs(w)) return true11 }12 color.set(v, BLACK) // полностью обработан13 return false14 }15 16 for (const v of graph.keys()) {17 if ((color.get(v) ?? WHITE) === WHITE && dfs(v)) return true18 }19 return false20}Проблема
Серое ребро в серую вершину = цикл: DFS трёхцветный.
Что вы видите
Белый/серый/чёрный; серые — в текущем стеке вызовов.
Как это работает
Ребро в серого предка замыкает цикл; чёрные — полностью обработаны. Основа детектора зависимостей компилятора и дедлоков.
Пошаговый разбор
- 01
Серый
Входим — красим.
- 02
Ребро
В серого = цикл!
- 03
Чёрный
Выходим — навсегда.
Complexity и ограничения
Сложность см. в шапке страницы.
Edge cases
- Пустой вход
Корректная тривиальная обработка.
- Вырожденный случай
Минимум работы — сразу ответ.
Где встречается в реальности
Компиляторы
Циклические зависимости.
Deadlock
Граф ожиданий.
make/cargo
Порядок сборки.
Связанные алгоритмы
«Зависимости зациклились? DFS знает»
Тот же сценарий StepSequence в вертикальной композиции — с safe zones и записью WebM ниже на странице.
Shorts 9:16
Вертикальная композиция строится той же последовательностью шагов, что и страница: safe zones отмечены пунктиром (там живёт UI платформ), биты сценария подсвечиваются по прогрессу. Кнопка записи сохраняет WebM — детерминированная StepSequence даёт воспроизводимый ролик без монтажа.