一、前言 很多情况下二级分类已经不能满足需要了,而网上可用的多级分类的例子实在是不好找,故 有此文。
bbs.blueidea/viewthread.php?tid=1182243 大家可以先看这个,它介绍了一种超级好的算法,反正我是看不大懂呀。
二、我们要解决的问题: 1、 分类算法常常表现为树的表示和遍历问题。那么,请问:如果用数据库中的一个 Table 来表达树 型分类,应该有几个字段? 2、 如何快速地从这个 Table 恢复出一棵树; 3、 如何判断某个分类是否是另一个分类的子类; 4、 如何查找某个分类的所有产品; 5、 如何生成分类所在的路径。 6、 如何新增分类;
三、递归实现的优点与缺点 该怎么实现多级分类呢? 估计首先想到的都是递归,实现简单,在指定节点(就是分类,下同)下添加、修改、删除 节点都不是
问题, 而且节点移动实现起来也不是很难,只是要注意移动目的父节点不能是当前节点的父节节点(等于没 移动),也不能是当前节点的子节点(类似于 window 文件夹,一个文件夹是不能移动到自己的字文 件夹里的)。 但是最愁人的是
搜索指定节点下的东西,怎么办?也就是上面的问题 3。记住,这是要包括 所有子节点的,难道还去递归吗?
四、介绍下我的简单算法(是我所用的,不是我发明的) 以常见的商品
系统为例。 4.1 表结构 [1]分类表,T_Sort,表结构如图一所示。其中 sortPath 保存的是节点路径,这是个 重点。 [2]商品表,T_Product,表结构如图二所示。 [center]图一
图二
[/center] 4.2 算法简要说明 [1]parentID 保存的自然是节点的父节点,如果一个节点的 parentID=0 时,认为它 是一级分类。 [2]一个节点的 sortPath 为它的父节点的 sortPath+自己的 sortID+","。 sortID=32 如 的节点的父节点是节点 21, 节点 21 的 sortPath 是"0,21,", 那么节点 32 的 sortPath 就是"0,21,32,"。 有点绕, 看图三清楚啦。 可能你想不通为啥最后要多个逗号啊, 后面你就明白啦。 所有节点的 sortPath 的左边两位都是"0,",因为它们都在根节点下。一个节点的 sortPath 一定包含在它的子节点的 sortPath 中。 [center] 图三
[/center] 4.3 代码重点讲解。 这里以我们要实现的功能为例讲解。 [1]添加节点 <1>选择父节点,可以是根节点,或是下级所有节点(最好列出一个树型菜单 让用户选择,别愁,可以实现),其实就是选择 parentID。 <2>如果 parentID=0,那么上级 sortPath="0,",如果 parentID<>0,那么到 表 T_Sort 根据 parentID 取得上级 sortPath。 <3>给 T_Sort 新增记录,sortPath=上级 sortPath +新记录的 sortID +","。 <4>范例代码见图 4、 5。 图 其中 noRecord, closeRs(),showMsg(),closeConn()
都是我定义的 Function 或
Sub, 它们的功能都是顾名思义的, 我就不说了。 注意一下, 如果你用 MS SQL, 代码略有不同。我也很奇怪 MS SQL 时,addNew 后,这个新的自动编号可以输出,但是和字符一连接 就没有了。各位如果知道为什么,还请相告。 [center] 图四
图五
[/center] [2]修改节点 节点的属性只有一个名字而已,直接 update 就可以了,就不说了。
[3]删除节点 <1>选择节点 <2>如果 parentID=0,报错,根节点不能删除。 <3>删除该节点及所有子节点。你可能想是不是很麻烦啊,哈哈,其实我只用 了一个 SQL 语句就搞定啦。
复制内容到剪贴板
代码: 代码:
(Access)sql="delete from T_Sort where Instr(sortPath,',"&;parentID&;",')>0"
复制内容到剪贴板
代码: 代码:
(MS
SQL)sql="delete
from
T_Sort
where
CHARINDEX(',"&;parentID&;",',sortPath)>0" 本算法的精华就在这里啦,仔细想想吧,sortPath 最后那个逗号的作用也在这里啦。 <4>删除上述所有节点下的商品。同上,表名不同而已。
复制内容到剪贴板
代码: 代码:
(Access)sql="delete
from
T_Product
where
Instr(sortPath,',"&