二叉树的数组表示
概述
二叉树除了常见的链式(指针)存储外,也可以用数组进行表示。
数组表示的核心思想:
- 按「层序遍历」顺序将节点依次放入数组。
- 通过下标映射公式定位父子节点,从而省去指针开销。
🚀 一句话速通
把整棵树按层序塞进数组,用下标公式代替指针,省内存、速度快。
📘 1️⃣ 基本原理
节点在数组中的下标 i | 对应关系 |
---|---|
左邻节点 | 2i + 1 |
右邻节点 | 2i + 2 |
上邻节点 | (i-1)//2 |
📝 根节点固定放在
0
号位置。
📂 2️⃣ 通用存储方案
⚠️ 非“完美树”会出现空洞,必须在数组里显式写 None
,否则无法重建唯一结构。
✅ 示例结构
索引 : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
值 : 1 2 3 4 None 6 7 8 9 None None 12 None None 15
🧩 3️⃣ Python 极简实现
class ArrayBinaryTree:
def __init__(self, arr):
self._tree = list(arr) # 复制一份,避免外部修改
# ---- 工具函数 ----
def size(self):
return len(self._tree)
def val(self, i):
return self._tree[i] if 0 <= i < self.size() else None
# ---- 下标公式 ----
def left(self, i): return 2 * i + 1
def right(self, i): return 2 * i + 2
def parent(self, i): return (i - 1) // 2
# ---- 遍历 ----
def level_order(self):
return [v for v in self._tree if v is not None]
def pre_order(self):
res = []
self._dfs(0, "pre", res)
return res
def in_order(self):
res = []
self._dfs(0, "in", res)
return res
def post_order(self):
res = []
self._dfs(0, "post", res)
return res
# ---- 深度优先通用 ----
def _dfs(self, i, order, res):
if self.val(i) is None:
return
if order == "pre":
res.append(self.val(i))
self._dfs(self.left(i), order, res)
if order == "in":
res.append(self.val(i))
self._dfs(self.right(i), order, res)
if order == "post":
res.append(self.val(i))
🏁 4️⃣ 运行示例
if __name__ == "__main__":
tree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]
abt = ArrayBinaryTree(tree)
print("层序:", abt.level_order())
print("前序:", abt.pre_order())
print("中序:", abt.in_order())
print("后序:", abt.post_order())
输出
层序: [1, 2, 3, 4, 6, 7, 8, 9, 12, 15]
前序: [1, 2, 4, 8, 9, 6, 12, 3, 7, 15]
中序: [8, 4, 9, 2, 12, 6, 1, 7, 15, 3]
后序: [8, 9, 4, 12, 6, 2, 15, 7, 3, 1]
⚖️ 5️⃣ 优点 vs 局限
序号 | 维度 | 优点 ✅ | 局限 ❌ |
---|---|---|---|
1 | 内存 | 连续存储,缓存友好 | 需要整块连续内存 |
2 | 空间 | 无需指针,结构紧凑 | 空洞多时利用率低 |
3 | 访问 | 随机定位节点 O(1) | 插入/删除需整体搬移元素 |