Files
hello-algo/ru/docs/chapter_tree/binary_tree_traversal.md
2026-01-20 15:08:42 +08:00

5.8 KiB
Raw Blame History

Обход двоичного дерева

С физической точки зрения дерево является структурой данных, основанной на связном списке, поэтому его обход осуществляется последовательным доступом к узлам через указатели. Однако, будучи нелинейной структурой данных, обход дерева сложнее, чем обход связного списка, и требует использования алгоритмов поиска.

Наиболее распространенные методы обхода двоичного дерева включают обход по уровням, прямой, симметричный и обратный обходы.

Обход по уровням

Обход по уровням осуществляется сверху вниз, выполняется последовательный обход двоичного дерева с посещением узлов на каждом уровне слева направо, как показано на рис. 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 демонстрируется рекурсивный процесс прямого обхода двоичного дерева, который можно разделить на два противоположных этапа: рекурсия и возврат.

  1. Рекурсия означает начало нового метода, в процессе которого программа посещает следующий узел.

  2. Возврат означает возвращение функции, что указывает на завершение посещения текущего узла.

=== "<1>" Рекурсивный процесс прямого обхода

=== "<2>" preorder_step2

=== "<3>" preorder_step3

=== "<4>" preorder_step4

=== "<5>" preorder_step5

=== "<6>" preorder_step6

=== "<7>" preorder_step7

=== "<8>" preorder_step8

=== "<9>" preorder_step9

=== "<10>" preorder_step10

=== "<11>" preorder_step11

Анализ сложности

Временная сложность O(n): все узлы посещаются один раз, что занимает O(n) времени.

Пространственная сложность O(n): в худшем случае, когда дерево вырождается в список, глубина рекурсии достигает n, система занимает O(n) пространства стека.