<?php
function display_tree($root) {
// 获得$root节点的左边和右边的值
$result = mysql_query('SELECT lft, rgt FROM tree '.
'WHERE title="'.$root.'";');
$row = mysql_fetch_array($result);
// 以一个空的$right栈开始
$right = array();
// 现在,获得$root节点的所有后序
$result = mysql_query('SELECT title, lft, rgt FROM tree '.
'WHERE lft BETWEEN '.$row['lft'].' AND '.
$row['rgt'].' ORDER BY lft ASC;');
// 显示每一行
while ($row = mysql_fetch_array($result)) {
// 检查栈里面有没有元素
if (count($right)>0) {
// 检查我们是否需要从栈中删除一个节点
while ($right[count($right)-1]<$row['rgt']) {
array_pop($right);
}
}
上面这种结构就是我推荐的,这种结构对于我们通常用的id-parentID结构增加了一个路径(path)列,好处就是可以直接通过查询path列来找 出某个节点的子树和路径,比如2号节点的子树可以通过先查2号子树的path,然后再用like ‘0,1,2%’方式来得到。其路径可以通过in(0,1,2)查询到。深度可以通过explode(‘,’,$path),然后看看数组个数就可以看出 节点的深度了,这样就可以构建出一个树形结构了。
path列的构建可以在原有id-parentID结构上增加,通过id和parentid可以很方便的构建出某个节点的子树的path列(需要递归算法)。
常用的函数可以有三个:
nav($node) 根据节点求出其路径,先找出节点path然后根据path用"select * from category where id in ($path)",就能求出其路径所有节点了,方便导航。
tree($node)根据节点求出其所有子树,先找出节点path,然后用"select * from category where path like ‘$path%’",就可以找出所有子节点啦,这里可以通过计算每个节点的path中有几个元素explode(‘,’$path)计算每个节点的深度。
re_path($node)根据节点,重新构建子树的path,这个需要利用ID和ParentID两列,利用递归逐步计算,因为只有在改变子树隶属关系和建立新节点的时候用到,所以计算量应该不是很多。
好了上面是这种算法的基本构想,大家有什么新的构想,提出来讨论一下。
附常用的三个函数:
function nav($id,$db){
$rs=$db->query("select * from category where id=’".$id."’");
$row=$rs->fetch();
$rs=$db->query("select * from category where id in (".$row[‘path’].") order by path");
return $rs->fetchall();
}
function tree($id,$db){
$rs=$db->query("select * from category where id=’".$id."’");
$row=$rs->fetch();
$rs=$db->query("select * from category where path like ‘".$row[‘path’]."%’ order by path");
$tree=$rs->fetchall();
foreach($tree as $key=>$row){
$depth=explode(‘,’,$row[‘path’]);
$depth=count($depth);
$tree[$key][‘depth’]=$depth;
}
return $tree;
}
function re_path($id,$parentpath=”,$db){//此函数使用前需要先获得父节点的path
if($parentpath<>”){$path=$parentpath.’,’.$id;}else{$path=$id;}
$sql="update category set path=’".$path."’ where id=’"$id"’";
$rs=$db->query($sql);
$sql="select * from category where parentid=’".$id."’";
$rs=$db->query($sql);
while($row=$rs->fetch()){
re_path($row[‘id’],$path,$db);
}
}