|
|
|
@ -18,6 +18,8 @@ comments: true
|
|
|
|
|
|
|
|
|
|
<p align="center"> 图 7-9 二叉树的层序遍历 </p>
|
|
|
|
|
|
|
|
|
|
### 1. 代码实现
|
|
|
|
|
|
|
|
|
|
广度优先遍历通常借助“队列”来实现。队列遵循“先进先出”的规则,而广度优先遍历则遵循“逐层推进”的规则,两者背后的思想是一致的。
|
|
|
|
|
|
|
|
|
|
=== "Java"
|
|
|
|
@ -322,9 +324,10 @@ comments: true
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**时间复杂度**:所有节点被访问一次,使用 $O(n)$ 时间,其中 $n$ 为节点数量。
|
|
|
|
|
### 2. 复杂度分析
|
|
|
|
|
|
|
|
|
|
**空间复杂度**:在最差情况下,即满二叉树时,遍历到最底层之前,队列中最多同时存在 $(n + 1) / 2$ 个节点,占用 $O(n)$ 空间。
|
|
|
|
|
- **时间复杂度 $O(n)$** :所有节点被访问一次,使用 $O(n)$ 时间,其中 $n$ 为节点数量。
|
|
|
|
|
- **空间复杂度 $O(n)$** :在最差情况下,即满二叉树时,遍历到最底层之前,队列中最多同时存在 $(n + 1) / 2$ 个节点,占用 $O(n)$ 空间。
|
|
|
|
|
|
|
|
|
|
## 7.2.2 前序、中序、后序遍历
|
|
|
|
|
|
|
|
|
@ -336,6 +339,10 @@ comments: true
|
|
|
|
|
|
|
|
|
|
<p align="center"> 图 7-10 二叉搜索树的前、中、后序遍历 </p>
|
|
|
|
|
|
|
|
|
|
### 1. 代码实现
|
|
|
|
|
|
|
|
|
|
深度优先搜索通常基于递归实现:
|
|
|
|
|
|
|
|
|
|
=== "Java"
|
|
|
|
|
|
|
|
|
|
```java title="binary_tree_dfs.java"
|
|
|
|
@ -747,13 +754,9 @@ comments: true
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**时间复杂度**:所有节点被访问一次,使用 $O(n)$ 时间,其中 $n$ 为节点数量。
|
|
|
|
|
|
|
|
|
|
**空间复杂度**:在最差情况下,即树退化为链表时,递归深度达到 $n$ ,系统占用 $O(n)$ 栈帧空间。
|
|
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
|
|
|
|
|
|
我们也可以不使用递归,仅基于迭代实现前、中、后序遍历,有兴趣的同学可以自行实现。
|
|
|
|
|
深度优先搜索也可以基于迭代实现,有兴趣的同学可以自行研究。
|
|
|
|
|
|
|
|
|
|
图 7-11 展示了前序遍历二叉树的递归过程,其可分为“递”和“归”两个逆向的部分。
|
|
|
|
|
|
|
|
|
@ -794,3 +797,8 @@ comments: true
|
|
|
|
|
![preorder_step11](binary_tree_traversal.assets/preorder_step11.png)
|
|
|
|
|
|
|
|
|
|
<p align="center"> 图 7-11 前序遍历的递归过程 </p>
|
|
|
|
|
|
|
|
|
|
### 2. 复杂度分析
|
|
|
|
|
|
|
|
|
|
- **时间复杂度 $O(n)$** :所有节点被访问一次,使用 $O(n)$ 时间。
|
|
|
|
|
- **空间复杂度 $O(n)$** :在最差情况下,即树退化为链表时,递归深度达到 $n$ ,系统占用 $O(n)$ 栈帧空间。
|
|
|
|
|