实现无限级分类的方法中,有一种是利用递归的方式,网上能找到的无限级分类的博客,几乎都是使用递归实现,因为它思想和实现都很简单;另外有一种全路径的方法来实现。
递归方式
递归实现无限级分类的实质: 数据结构中递归实现遍历树 的过程,所以应该将重点集中在树的遍历上面。
其实递归实现无限级最常用的是双亲表示法。
双亲表示法:每个节点都会保存父节点的标识,通过这个标识可以找到他的父节点,但是没有保存他的孩子的标识,即,如果不遍历家族树的话,一个节点是不知道他的子节点的标识,甚至都不知道是否有子节点。
下面是一棵目录树:
用表格的形式来表示就是下面这样:
mysql> select * from category;
+----+-----------+------------+-----------+
| id | cate_name | cate_order | parent_id |
+----+-----------+------------+-----------+
| 1 | AAAA | 3 | 0 |
| 2 | BBBB | 2 | 1 |
| 3 | CCCC | 4 | 1 |
| 4 | DDDD | 3 | 1 |
| 5 | EEEE | 2 | 2 |
| 6 | FFFF | 3 | 2 |
| 7 | GGGG | 7 | 3 |
| 8 | HHHH | 4 | 4 |
| 9 | IIII | 3 | 4 |
| 10 | JJJJ | 2 | 4 |
+----+-----------+------------+-----------+
使用递归来遍历一个由双亲表示法描述的树的过程大致如下,以上面的树结构为例:
1、首先找到A节点,然后遍历整个树的所有节点,找哪些节点的父亲是A,找出的节点就是A的孩子节点,比如B,C,D。
2、找到B节点后,然后遍历整个树的所有节点,找哪些节点的父亲是B,找出的节点就是B的孩子节点,比如E、F。
3、找到C节点后,然后遍历整个树的所有节点,找哪些节点的父亲是C,找出的节点就是C的孩子节点,比如G。
4、找到D节点后,然后遍历整个树的所有节点,找哪些节点的父亲是D,找出的节点就是D的孩子节点,比如H、I、J。
5、依次对E、F、G、H、I、J进行上面的操作,发现他们都没有子节点了。
问题:怎么判断一个节点是不是另外一个节点的孩子呢?
回答:注意数据库中有个id和parent_id,id就是本节点的标识,parent_id记录的父节点的标识。要判断B节点是不是A节点的孩子,只需要看B节点的parent_id字段等于A节点的id即可,如果等于,那B就是A的子节点,否则B就不是A的子节点。
问题:这是树的递归遍历,和无限分类有什么关系呢?
回答:好好想想吧,无限分类是不是类似于目录形式,每个目录下都可能有目录,树的某个节点是不是可能有子节点,子节点是不是可能还有他自己的子节点?
实现:
<?php
$mysqli = new Mysqli("127.0.0.1","root","123456","test");
$mysqli_result = $mysqli->query("select * from category order by id asc");
$res = $mysqli_result->fetch_all(MYSQLI_ASSOC);
/*
*@$res 存储分类信息的数组
*@$parent_id 父节点的id
*@$level 记录当前的节点在树形图中的层级
*/
function showCate($res,$parent_id=0,$level=0){
static $tree;
foreach($res as $k => $cate){
if($parent_id == $cate['parent_id']){
$prefix = str_repeat(" ",$level)."|————";
$tree[] = $prefix.$cate['cate_name'];
showCate($res,$cate['id'],$level+1);
}
}
return $tree;
}
$cate_tree = showCate($res,0,0);
foreach($cate_tree as $cate){
echo $cate."\n";
}
?>
运行结果:
全路径方式