BFS (breadth-first search) исследует граф «кругами»: сначала все соседи старта (расстояние 1), потом соседи соседей (расстояние 2) и так далее. Благодаря этому BFS находит кратчайший путь в невзвешенном графе — по числу рёбер. Как и обход дерева по уровням, BFS использует очередьdeque.
BFS расходится волнами: число в вершине — расстояние от старта S.
▶ bfs.py
Кратчайший путь в рёбрах
Чтобы узнать расстояние от старта до каждой вершины, в очереди храним пару «вершина и её дистанция» — или ведём словарьКоллекция пар «ключ → значение»: {"a": 1}. Быстрый доступ по ключу. По-английски dict.dist. Когда впервые доходим до вершины, записанное расстояние и есть кратчайшее: BFS гарантирует, что раньше всех приходит по самому короткому пути.
▶ shortest.py
📝Заметка
DFS или BFS? Для проверки достижимости и обхода всего графа подойдёт любой. Но если нужен именно кратчайший путь по числу рёбер — берите BFS: он находит ближайшие вершины первыми. DFS этого не гарантирует. Для путей с разными «весами» рёбер используют алгоритмЧёткая последовательность шагов для решения задачи за конечное число действий. Дейкстры (продвинутая тема).
💡Совет
Предскажите вывод. Для графа-цепочки A → B → C → D функцияИменованный блок кода, который можно вызывать многократно. Может принимать аргументы и возвращать результат.distances вернёт расстояния от A. Чему будет равно distances(graph, "A")["D"]?
▶ predict-dist.py
Вернётся 3: до D нужно пройти три ребра A→B→C→D. BFS аккуратно наращивает расстояние на 1 на каждой волне.
Обнаружение цикла
Частый вопрос: «есть ли в графе циклКонструкция, повторяющая блок кода: for перебирает элементы, while — пока условие истинно.?» Для ненаправленного графа идея такая: запускаем DFS и, если встречаем уже посещённую вершину, которая не является родителем текущей (откуда мы только что пришли), — значит, нашли цикл.
▶ has-cycle.py
⚠️ Частые ошибки новичков
Ошибка. В BFS добавлять вершину в visited не при помещении в очередь, а при извлечении. Тогда одну вершину можно положить в очередь несколько раз (через разных соседей), и обход замедлится или исказит расстояния. Правильно: помечаем посещённой сразу, как кладём в очередь. Запустите код и сравните.
▶ broken-bfs.py
Заданиерешение.py
Напишите функцию shortest_len(graph, start, target), возвращающую длину кратчайшего пути (в рёбрах) от start до target через BFS. Если пути нет — верните -1.
Заданиерешение.py
Напишите функцию count_components(graph), считающую число компонент связности — групп вершин, не соединённых между собой. Запускайте обход от каждой непосещённой вершины.
❓Проверь себя
Какой обход находит кратчайший путь по числу рёбер?
Какая структура данных лежит в основе BFS?
Что такое компонента связности?
ℹ️Важно
✅ Что вы узнали
BFS обходит граф волнами и находит кратчайший путь в рёбрах.
BFS работает на очереди deque; вершину помечают при добавлении.
Словарь расстояний даёт длину кратчайшего пути до каждой вершины.
Цикл ищут через DFS, сравнивая соседа с родителем.
Число компонент связности — запуск обхода от каждой непосещённой вершины.
Комментарии
Загрузка…
Загрузка комментариев…