二叉树的数组表示
二叉树的数组表示
Aristore以下是二叉树的结构:
1 | A |
数组表示
数组构造规则:
- 层次遍历(从上到下,从左到右),每个节点都按照对应位置存入数组。
- 如果某个位置的子节点缺失,用
None
占位。
用数组表示上述二叉树:
1 | ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', None, 'J', None, None, None, None] |
如何理解:
- 索引
0
存储根节点A
。 - 索引
1
存储A
的左子节点B
;索引2
存储A
的右子节点C
。 - 索引
3
和4
分别存储B
的左子节点D
和右子节点E
。 - 索引
5
和6
分别存储C
的左子节点F
和右子节点G
。 - 索引
7
和8
分别存储D
的左子节点H
和右子节点I
。 - 索引
9
是E
的左子节点(缺失,用None
占位)。 - 索引
10
存储E
的右子节点J
。 - 后面索引
11
到14
是F
和G
的子节点(均为空,用None
占位)。
数组中索引的关系
给定节点索引 i
:
- 左子节点:索引为
2 * i + 1
。 - 右子节点:索引为
2 * i + 2
。 - 父节点:索引为
(i - 1) // 2
。
例如:
- 节点
B
在索引1
:- 左子节点是
D
,索引为2 * 1 + 1 = 3
。 - 右子节点是
E
,索引为2 * 1 + 2 = 4
。
- 左子节点是
- 节点
E
在索引4
:- 左子节点为
None
,索引为9
。 - 右子节点是
J
,索引为10
。
- 左子节点为
二叉树的遍历实现
我们接下来实现 前序遍历、中序遍历、后序遍历 和 层次遍历,并直接从数组中解析出结果。
遍历代码
1 | # 二叉树的数组表示 |
输出结果
1 | 前序遍历: ['A', 'B', 'D', 'H', 'I', 'E', 'J', 'C', 'F', 'G'] |
数组表示的优缺点
优点
- 索引访问快速:通过索引关系,能快速找到父节点或子节点,特别适合需要频繁查找关系的操作。
- 简洁表示:数组在表示 完全二叉树 时无需额外空间,所有节点按顺序排列,无需指针。
- 易于序列化和存储:二叉树可以直接转换为一个数组存储或传递,尤其是在网络传输或持久化时非常方便。
缺点
- 浪费空间:对于不完全或不平衡的二叉树,需要大量的
None
占位,浪费空间。例如,G
的子节点全为空,数组中填充了许多None
。 - 不灵活:数组的大小在初始化时需要规划好,插入或删除节点时需要重新调整数组,效率较低。
- 不适合深度不平衡的树:对于深度较大的不平衡树(例如左斜树或右斜树),数组会极其稀疏,浪费大量存储空间。
总结
数组表示二叉树适用于 完全二叉树 或 接近完全二叉树,对于深度大且不平衡的二叉树不太合适。None
在数组中用于占位以保证层次关系,这种方式虽然浪费了一些空间,但换取了简化的父子关系操作。
评论
匿名评论隐私政策