树形数据结构的设计的几种方式
一、邻接表
1.1. 实现方式
- 每个记录增加一个 parent_id; [id, parent_id]
id | name | parent_id |
---|---|---|
1 | 华府 | |
2 | 华太师 | 1 |
3 | 华夫人 | 1 |
1.2. 操作说明
无
1.3. 优点/缺点
- 查询所有子节点:需要递归
- 树形形遍历:需要递归
- 插入:简单
- 删除:需要递归删除
- 移动:简单
- 冗余:无
- 是否有层级限制:无
二、嵌套表(闭包表)
2.1. 实现方式:
- 主表:[id, parent_id]
id | name | parent_id |
---|---|---|
1 | 华府 | |
2 | 华太师 | 1 |
3 | 华夫人 | 1 |
4 | 武状元 | 2 |
5 | 管家 | 2 |
6 | 华安 | 5 |
- 嵌套子表:[id, food_id, parent_id]
id | parent_id | foot_id |
---|---|---|
1 | 1 | 2 |
2 | 1 | 3 |
3 | 1 | 4 |
4 | 1 | 5 |
5 | 1 | 6 |
6 | 2 | 4 |
7 | 2 | 5 |
8 | 2 | 6 |
9 | 5 | 6 |
2.2. 操作说明
无
2.3. 优点/缺点
- 查询所有子节点:简单,需要关联表
- 树形形遍历:需要递归
- 新增:一般,需要更新嵌套表
- 删除:一般,需要更新嵌套表
- 移动:一般,需要更新嵌套表
- 冗余:数据冗余,需要额外的存储空间(Cn2:C(n,2)),随着层级的增加,所需空间迅速增加
- 是否有层级限制:无
2.3. 优点:
- 查询、删除一个表下所有子节点方便,select foot_id from table_name where parent_id = x;
2.4. 缺点:
- 需要额外的存储空间(Cn2:C(n,2)),随着层级的增加,所需空间也增加。
- 新增、删除需要额外的维护关系的成本。
三、左右值编码
3.1. 实现方式:
- 每个记录增加左右编码:[id, parent_id, left, right]。
- 左右编码确定方式:采用先序遍历算法,每个节点编号加1。
- 左右编码连起来相当于一个有序数列。
id | name | parent_id | left | right |
---|---|---|---|---|
1 | 华府 | 1 | 20 | |
2 | 华太师 | 1 | 2 | 9 |
3 | 华夫人 | 1 | 10 | 19 |
4 | 武状元 | 2 | 3 | 4 |
5 | 管家 | 2 | 5 | 8 |
6 | 华安 | 5 | 6 | 7 |
7 | 春香 | 3 | 11 | 12 |
8 | 夏香 | 3 | 13 | 14 |
9 | 秋香 | 3 | 15 | 16 |
10 | 冬香 | 3 | 17 | 18 |