四叉树与八叉树¶
概述¶
四叉树(Quadtree)和八叉树(Octree)是用于空间划分的树形数据结构。四叉树将2D空间递归划分为四个象限,八叉树将3D空间递归划分为八个卦限,广泛应用于图像处理、游戏开发、空间索引等领域。
核心思想:当节点包含的对象超过阈值时,将空间均匀分割成 2^d 个子区域(d为维度),每个子区域对应一个子节点,直到满足停止条件。
四叉树¶
四叉树结构可视化¶
空间划分过程:
原始空间
第一次分裂(超过容量4)
继续分裂(左上象限超过容量)
四叉树节点结构¶
graph TB
subgraph 四叉树节点结构
root["根节点<br/>整个空间"]
nw["NW<br/>左上"]
ne["NE<br/>右上"]
sw["SW<br/>左下"]
se["SE<br/>右下"]
root --> nw
root --> ne
root --> sw
root --> se
end
style root fill:#4CAF50,color:#fff
style nw fill:#2196F3,color:#fff
style ne fill:#FF9800,color:#fff
style sw fill:#9C27B0,color:#fff
style se fill:#E91E63,color:#fff
象限编号:
数据结构定义¶
创建四叉树¶
分裂节点¶
分裂过程可视化:
flowchart TD
A["节点点数 > MAX"]
B["计算中心点"]
C["创建4个子节点"]
D["重新分配点到子节点"]
E["标记为非叶子节点"]
A --> B --> C --> D --> E
style A fill:#FFEBEE
style E fill:#E8F5E9
插入操作¶
范围查询¶
范围查询示意:
查询区域(虚线框)
结果: A, B, C (查询区域内的点)
八叉树¶
八叉树结构可视化¶
3D空间划分:
3D空间分裂与卦限编号
0: 左下后 (x<mid, y<mid, z<mid)
1: 左下前 (x<mid, y<mid, z>mid)
2: 右下后 (x>mid, y<mid, z<mid)
3: 右下前 (x>mid, y<mid, z>mid)
4: 左上后 (x<mid, y>mid, z<mid)
5: 左上前 (x<mid, y>mid, z>mid)
6: 右上后 (x>mid, y>mid, z<mid)
7: 右上前 (x>mid, y>mid, z>mid)
数据结构定义¶
创建八叉树节点¶
分裂八叉树节点¶
八叉树插入¶
C++ 实现¶
四叉树/八叉树变体¶
| 变体 | 特点 | 应用 |
|---|---|---|
| 点四叉树 | 存储点数据 | 空间索引 |
| 区域四叉树 | 存储区域信息 | 图像处理 |
| 边四叉树 | 存储边界信息 | 地理信息系统 |
| PR四叉树 | 点区域四叉树 | 数据库索引 |
| 线性四叉树 | 用编码表示节点 | 压缩存储 |
graph TB
subgraph 四叉树变体
A["四叉树"]
B["点四叉树"]
C["区域四叉树"]
D["PR四叉树"]
E["线性四叉树"]
A --> B
A --> C
A --> D
A --> E
end
style A fill:#4CAF50,color:#fff
时间复杂度¶
四叉树¶
| 操作 | 平均 | 最坏 | 说明 |
|---|---|---|---|
| 插入 | O(log n) | O(n) | 依赖点分布 |
| 删除 | O(log n) | O(n) | |
| 范围查询 | O(log n + m) | O(n) | m为结果数 |
| 最近邻 | O(log n) | O(n) |
八叉树¶
| 操作 | 平均 | 最坏 | 说明 |
|---|---|---|---|
| 插入 | O(log n) | O(n) | |
| 范围查询 | O(log n + m) | O(n) | |
| 最近邻 | O(log n) | O(n) |
性能依赖:四叉树/八叉树的性能高度依赖数据分布。点均匀分布时效率最高,点聚集时可能退化为线性结构。
空间复杂度¶
| 结构 | 空间复杂度 | 说明 |
|---|---|---|
| 四叉树 | O(n) | n为点数 |
| 八叉树 | O(n) | n为点数 |
| 最大深度 | O(log n) | 点均匀分布 |
应用场景¶
四叉树应用¶
| 应用领域 | 具体场景 |
|---|---|
| 图像处理 | 图像压缩、区域分割 |
| 地形渲染 | LOD(细节层次)管理 |
| 碰撞检测 | 2D空间物体检测 |
| 地理信息系统 | 空间索引、地图渲染 |
| 游戏 | 视锥剔除、地形管理 |
八叉树应用¶
| 应用领域 | 具体场景 |
|---|---|
| 点云处理 | 点云压缩、法向量估计 |
| 3D碰撞检测 | 空间划分、碰撞检测 |
| 体素渲染 | 体素数据管理 |
| 3D图形 | 视锥剔除、LOD |
| 医学影像 | CT/MRI数据处理 |
四叉树 vs 八叉树 vs 其他结构¶
| 结构 | 维度 | 子节点数 | 优势 | 劣势 |
|---|---|---|---|---|
| 四叉树 | 2D | 4 | 简单、高效 | 仅限2D |
| 八叉树 | 3D | 8 | 适合3D | 高维扩展差 |
| KD树 | 任意 | 2 | 维度无关 | 动态更新难 |
| R树 | 任意 | M | 动态更新 | 实现复杂 |
选择建议:2D空间优先选择四叉树,3D空间选择八叉树,更高维度或动态更新频繁时选择R树或KD树。
实际应用示例¶
图像压缩(区域四叉树)¶
原始图像
→
压缩后
1: 黑色区域
0: 白色区域
点云压缩(八叉树)¶
| C++ | |
|---|---|
地形LOD(四叉树)¶
地形渲染LOD
近距离(高细节)
→
远距离(低细节)
参考资料¶
- Finkel, R. A., Bentley, J. L. (1974). Quad Trees: A Data Structure for Retrieval on Composite Keys
- Samet, H. (1990). The Design and Analysis of Spatial Data Structures
- Meagher, D. (1982). Geometric Modeling Using Octree Encoding