First version.

This commit is contained in:
krahets
2026-01-20 15:08:42 +08:00
parent 2213a59ff6
commit 8071daddaa
106 changed files with 11790 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
# Обход двоичного дерева
С физической точки зрения дерево является структурой данных, основанной на связном списке, поэтому его обход осуществляется последовательным доступом к узлам через указатели. Однако, будучи нелинейной структурой данных, обход дерева сложнее, чем обход связного списка, и требует использования алгоритмов поиска.
Наиболее распространенные методы обхода двоичного дерева включают обход по уровням, прямой, симметричный и обратный обходы.
## Обход по уровням
Обход по уровням осуществляется сверху вниз, выполняется последовательный обход двоичного дерева с посещением узлов на каждом уровне слева направо, как показано на рис. 7.9.
Обход по уровням по своей сути является обходом в ширину, также называемым поиском в ширину, который характеризуется постепенно расширяющимся кольцом от центра к периферии.
![Обход двоичного дерева по уровням](../assets/media/image228.jpeg)
### Код реализации
Обход в ширину обычно реализуется с использованием очереди. Очередь следует принципу «первый вошел -- первый вышел», а обход в ширину -- принципу «поэтапное продвижение», что делает их концептуально схожими. Ниже приведен код реализации.
```src
[file]{binary_tree_bfs}-[class]{}-[func]{level_order}
```
### Анализ сложности
**Временная сложность** *O*(*n*): каждый узел посещается один раз, что занимает *O*(*n*) времени выполнения, где *n* -- количество узлов.
**Пространственная сложность** *O*(*n*): в худшем случае, т. е. в полном двоичном дереве, до достижения самого нижнего уровня в очереди может находиться одновременно (*n* + 1)/2 узлов, что занимает *O*(*n*) пространства.
## Прямой, симметричный и обратный обходы
Прямой, симметричный и обратный обходы относятся к обходам в глубину, также называемым поиск в глубину, который характеризуется подходом «сначала до конца, затем возврат и продолжение».
На рис. 7.10 демонстрируется принцип работы обхода в глубину для двоичного дерева. **Обход в глубину можно представить как обход двоичного дерева по периметру**, при этом на каждом узле встречаются три позиции, соответствующие прямому, симметричному и обратному обходам.
![Прямой, симметричный и обратный обходы двоичного дерева](../assets/media/image237.jpeg)
### Код реализации
Поиск в глубину обычно реализуется на основе рекурсии.
```src
[file]{binary_tree_dfs}-[class]{}-[func]{post_order}
```
На рис. 7.11 демонстрируется рекурсивный процесс прямого обхода двоичного дерева, который можно разделить на два противоположных этапа: рекурсия и возврат.
1. Рекурсия означает начало нового метода, в процессе которого программа посещает следующий узел.
2. Возврат означает возвращение функции, что указывает на завершение посещения текущего узла.
=== "<1>"
![Рекурсивный процесс прямого обхода](../assets/media/image246.jpeg)
=== "<2>"
![preorder_step2](../assets/media/image249.jpeg)
=== "<3>"
![preorder_step3](../assets/media/image251.jpeg)
=== "<4>"
![preorder_step4](../assets/media/image253.jpeg)
=== "<5>"
![preorder_step5](../assets/media/image256.jpeg)
=== "<6>"
![preorder_step6](../assets/media/image259.jpeg)
=== "<7>"
![preorder_step7](../assets/media/image261.jpeg)
=== "<8>"
![preorder_step8](../assets/media/image263.jpeg)
=== "<9>"
![preorder_step9](../assets/media/image266.jpeg)
=== "<10>"
![preorder_step10](../assets/media/image269.jpeg)
=== "<11>"
![preorder_step11](../assets/media/image271.jpeg)
### Анализ сложности
**Временная сложность** *O*(*n*): все узлы посещаются один раз, что занимает *O*(*n*) времени.
**Пространственная сложность** *O*(*n*): в худшем случае, когда дерево вырождается в список, глубина рекурсии достигает *n*, система занимает *O*(*n*) пространства стека.