Как узнать
кратчайший путь, когда каждый шаг стоит одинаково, минимум ходов или дерево по уровням.
Как решать такие задачи
- Если корень может быть none, сразу верни пустой ответ.
- Положи корень в очередь.
- В начале каждого круга запомни size = queue.size и возьми ровно столько узлов: это один уровень.
- Клади левого и правого потомка каждого узла в конец, пропуская none. Для самого правого значения, среднего или зигзага меняется только то, что ты делаешь с уровнем.
Вариант: Граф
То же, но в графе к одной вершине ведут разные пути, поэтому посещённые вершины отмечаем. Первый раз, когда волна дошла до вершины, — это самый короткий путь до неё.
- Определи, что здесь вершина (клетка, слово, состояние) и кто её соседи.
- Положи старт в очередь и сразу отметь посещённым.
- Бери из начала. Каждого непосещённого соседа клади в конец и сразу отмечай.
- Для расстояний иди по уровням или храни расстояние вместе с вершиной. Остановись, когда дошёл до цели.
Вариант: Сетка
То же, но на сетке: клетки — это вершины, а соседние клетки связаны. Волна расходится от старта, и шаг, на котором она дошла до клетки, — это кратчайшее расстояние до неё.
- Считай каждую открытую клетку вершиной: её соседи — клетки сверху, снизу, слева и справа, которые внутри сетки и не стены.
- Заведи таблицу dist, заполненную none. Поставь старту 0 и положи его в очередь.
- Бери клетку из начала. Каждому соседу без расстояния ставь на 1 больше, чем у неё, и клади его в конец.
- Останавливайся, когда цель выходит из очереди: её расстояние уже окончательное. Клетка, до которой не дошли, остаётся none.
- Если источников несколько, например все гнилые апельсины сразу, положи их все в очередь с расстоянием 0 до начала цикла.
Вариант: Состояния
То же, но вершины — не места, а состояния, например слова, которые отличаются одной буквой. Граф заранее не строим: соседей состояния придумываем, когда до него дошли.
- Реши, что такое одно состояние: слово, положение колёсиков замка, клетка на доске. Один ход — одно ребро.
- Напиши функцию, которая строит соседей состояния; весь граф заранее строить не нужно.
- Запусти BFS от старта и храни число ходов в dist. Состояние, которое уже есть в dist, пропускают, поэтому в очередь ничего не попадает дважды.
- Настольная игра устроена так же: в «Змеях и лестницах» каждая клетка — вершина, бросок кубика даёт до шести соседей, а змея или лестница переносит дальше, прежде чем клетку кладут в очередь.
Где встречается
- Скачивание сайта. wget --recursive скачивает сайт волнами: сначала стартовую страницу, потом страницы по ссылкам с неё, потом следующий слой. Ключ -l ограничивает, сколько волн пройти.
- Сборка мусора. Копирующий сборщик мусора по алгоритму Чейни переносит живые объекты в новую область волнами: сначала те, на которые ссылается программа, потом те, на которые ссылаются они. Очередью служит сама новая область памяти.