5.8 KiB
Обход двоичного дерева
С физической точки зрения дерево является структурой данных, основанной на связном списке, поэтому его обход осуществляется последовательным доступом к узлам через указатели. Однако, будучи нелинейной структурой данных, обход дерева сложнее, чем обход связного списка, и требует использования алгоритмов поиска.
Наиболее распространенные методы обхода двоичного дерева включают обход по уровням, прямой, симметричный и обратный обходы.
Обход по уровням
Обход по уровням осуществляется сверху вниз, выполняется последовательный обход двоичного дерева с посещением узлов на каждом уровне слева направо, как показано на рис. 7.9.
Обход по уровням по своей сути является обходом в ширину, также называемым поиском в ширину, который характеризуется постепенно расширяющимся кольцом от центра к периферии.
Код реализации
Обход в ширину обычно реализуется с использованием очереди. Очередь следует принципу «первый вошел -- первый вышел», а обход в ширину -- принципу «поэтапное продвижение», что делает их концептуально схожими. Ниже приведен код реализации.
[file]{binary_tree_bfs}-[class]{}-[func]{level_order}
Анализ сложности
Временная сложность O(n): каждый узел посещается один раз, что занимает O(n) времени выполнения, где n -- количество узлов.
Пространственная сложность O(n): в худшем случае, т. е. в полном двоичном дереве, до достижения самого нижнего уровня в очереди может находиться одновременно (n + 1)/2 узлов, что занимает O(n) пространства.
Прямой, симметричный и обратный обходы
Прямой, симметричный и обратный обходы относятся к обходам в глубину, также называемым поиск в глубину, который характеризуется подходом «сначала до конца, затем возврат и продолжение».
На рис. 7.10 демонстрируется принцип работы обхода в глубину для двоичного дерева. Обход в глубину можно представить как обход двоичного дерева по периметру, при этом на каждом узле встречаются три позиции, соответствующие прямому, симметричному и обратному обходам.
Код реализации
Поиск в глубину обычно реализуется на основе рекурсии.
[file]{binary_tree_dfs}-[class]{}-[func]{post_order}
На рис. 7.11 демонстрируется рекурсивный процесс прямого обхода двоичного дерева, который можно разделить на два противоположных этапа: рекурсия и возврат.
-
Рекурсия означает начало нового метода, в процессе которого программа посещает следующий узел.
-
Возврат означает возвращение функции, что указывает на завершение посещения текущего узла.
Анализ сложности
Временная сложность O(n): все узлы посещаются один раз, что занимает O(n) времени.
Пространственная сложность O(n): в худшем случае, когда дерево вырождается в список, глубина рекурсии достигает n, система занимает O(n) пространства стека.












