径中, 然后我们再查询Red的父节点并把它也添加到路径中,以此类推直到最高层的"Food"
<?php // $node 是那个最深的节点 function get_path($node) { // 查询这个节点的父节点 $result = mysql_query(''SELECT parent FROM tree ''. ''WHERE name="''.$node.''";''); $row = mysql_fetch_array($result);
// 用一个数组保存路径 $path = array();
// 如果不是根节点则继续向上查询 // (根节点没有父节点) if ($row[''parent'']!='''') { // the last part of the path to $node, is the name // of the parent of $node $path[] = $row[''parent''];
// we should add the path to the parent of this node // to the path $path = array_merge(get_path($row[''parent'']), $path); }
// return the path return $path; } ?> 如果对"Cherry"使用这个函数:print_r(get_path(''Cherry'')),就会得到这样的一个数组了:
Array ( [0] => Food [1] => Fruit [2] => Red ) 接下来如何把它打印成你希望的格式,就是你的事情了。 缺点:这种方法很简单,容易理解,好上手。但是也有一些缺点。主要是因为运行速度很慢,由于得到每个节点都需要进行数据库查询,数据量大的时候要进行很多查询才能完成一个树。另外由于要进行递归运算,递归的每一级都需要占用一些内存所以在空间利用上效率也比较低。
现在让我们看一看另外一种不使用递归计算,更加快速的方法,这就是预排序遍历树算法(modified preorder tree traversal algorithm) 这种方法大家可能接触的比较少,初次使用也不像上面的方法容易理解,但是由于这种方法不使用递归查询算法,有更高的查询效率。
我们首先将多级数据按照下面的方式画在纸上,在根节点Food的左侧写上 1 然后沿着这个树继续向下 在 Fruit 的左侧写上 2 然后继续前进,沿着整个树的边缘给每一个节点都标上左侧和右侧的数字。最后一个数字是标在Food 右侧的 18。 在下面的这张图中你可以看到整个标好了数字的多级结构。(没有看懂?用你的手指指着数字从1数到18就明白怎么回事了。还不明白,再数一遍,注意要移动你的手指)。 这些数字标明了各个节点之间的关系,"Red"的号是3和6,它是 "Food" 1-18 的子孙节点。 同样,我们可以看到 所有左值大于2和右值小于11的节点 都是"Fruit" 2-11 的子孙节点
1 Food 18 | +---------------------------------------+ | | 2 Fruit 11 12 Meat 17 | | +------------------------+ +---------------------+ | | | | 3 Red 6 7 Yellow 10 13 Beef 14 15 Pork 16 | | 4 Cherry 5 8 Banana 9
这样整个树状结构可以通过左右值来存储到数据库中。继续之前,我们看一看下面整理过的数据表。
+-----------------------+-----+-----+ | parent | name | lft | rgt | +-----------------------+-----+-----+ | | Food | 1 | 18 | | Food | Fruit | 2 | 11 | | Fruit | Red | 3 | 6 | | Red | Cherry | 4 | 5 | | Fruit | Yellow | 7 | 10 | | Yellow | Banana | 8 | 9 | | Food | Meat | 12 | 17 | | Meat | Beef | 13 | 14 | | Meat | Pork | 15 | 16 | +-----------------------+-----+-----+ 注意:由于"left"和"right"在 SQL中有特殊的意义,所以我们需要用"lft"和"rgt"来表示左右字段。 另外这种结构中不再需要"parent"字段来表示树状结构。也就是 说下面这样的表结构就足够了。
+------------+-----+-----+ | name | lft | rgt | +------------+-----+-----+ | Food | 1 | 18 | | Fruit | 2 | 11 | | Red | 3 | 6 | | Cherry | 4 | 5 | | Yellow | 7 | 10 | | Banana | 8 | 9 | | Meat | 12 | 17 | | Beef | 13 | 14 | | Pork | 15 | 16 | +------------+-----+-----+ 好了我们现在可以从数据库中获 |