什么是预排序遍历树算法(MPTT,Modified Preorder Tree Traversal)
在了解什么是『预排序遍历树算法』之前,我们先思考一个问题如何处理『多级分类的子分类查询』。例如:

要存储表示层级关系的数据,一种最简单的方案,存储当前分类的名称,以及上一级分类的名称,通常我们称这种存储结构为『邻接表』。
数据库存储结构:
fruit
food
meat
food
apple
fruit
breef
meat
pork
meat
这种方式有什么问题:查询效率过低。当我们在程序里查询 food 的子分类时,要先在数据库中,查询 food 的一级子分类(fruit、meat)、在对一级分类的子分类进行递归查询,需要进行 logN 次( N 为子分类个数) I/O 操作(向数据库进行查询),这样的查询效率不高,但是很容易实现。
而 MPTT 预排序生成树算法正是为了解决多层级关系数据的查询效率问题。
1. MPTT 是什么?
MPTT(Modified Preorder Tree Taversal)预排序遍历树算法,主要应用于层级关系的存储和遍历。
在 MPTT 中是如何表示层级关系的:

MTTP 不直接存储父分类信息,而是通过 left、right 指来表示层级关系。
还是以 food 为例,我们从头开始构建一棵『预排序遍历树』。
然后开始插入 food 的一级子分类,根据当前分类的 left_value 来确定插入分类的左右值,同时更新受影响的其他分类。

show code,插入子分类
除了插入子分类的方式,我们还可以选择 插入同级分类,和插入子分类的区别在于,插入点的左右值取决于被插入点的 right_value。
删除指定分类,也等于删除包括指定分类在内的所有子分类,所有受影响左右子分类都受影响。
那如何 查询指定分类的子分类 呢?
通过 MPTT 我们查询某一特定分类的子分类信息只要做两次查询操作,解决了『邻接表』递归查询的低效查询问题。
2. 『邻接表』和『预排序遍历树』的优劣
『邻接表』,适用于 增删改 操作较多的场景,每次删改只需要修改一条数据。在查询方面,随着 分类层级的增加『邻接表』的递归查询效率逐渐降低。
『预排序遍历树』,适用于 查询 操作较多的场景,查询的效率不受分类层级的增加的影响,但是随着数据的增多,每增删数据,都要同时操作多条受影响数据,执行效率逐渐下降。
具体要选择哪一种存储结构和算法,需要根据具体的应用场景来做选择。
最后更新于
这有帮助吗?