2011-09-01 134 views
2

我已经实现了修改先序树遍历as explained here。我的树是这样的:修改先序树遍历的路径

+-------+-----------+-----+-----+ 
| ref | name  | lft | rgt | 
+-------+-----------+-----+-----+ 
| NULL | base  | 1 | 8 | 
|  2 | basic  | 2 | 3 | 
| NULL | listener | 4 | 7 | 
|  1 | test  | 5 | 6 | 
+-------+-----------+-----+-----+ 

一切都OK了,但现在我试图执行基于路径上的PHP搜索功能,它是这样的:

$result = searchTree('base.listener.test'); 
// Now $result is an array with node {1, test} 

这意味着, searchTree根据给定的路径返回一个子树。如果路径不存在,它将返回一个空数组。

我目前的实现是加载树成PHP数组,然后将其拆分路径,并通过阵列走一个循环的功能。它似乎是一个不可扩展的实现......任何更好的实现(可能使用mySQL查询?)。

我目前的实现是这样的。首先,我得到整个树(SELECT * FROM树),然后我执行此功能以使从这个数据的多维数组:

function create_tree($results) { 
    $return = $results[0]; 
    array_shift($results); 

    if ($return['lft'] + 1 == $return['rgt']) 
     $return['leaf'] = true; 
    else { 
     foreach ($results as $key => $result) { 
      if ($result['lft'] > $return['rgt']) 
       break; 
      if ($rgt > $result['lft']) 
       continue; 
      $return['children'][] = create_tree(array_values($results)); 
      foreach ($results as $child_key => $child) { 
       if ($child['rgt'] < $result['rgt']) 
        unset($results[$child_key]); 
      } 
      $rgt = $result['rgt']; 
      unset($results[$key]); 
     } 
    } 

    unset($return['lft'],$return['rgt']); 
    return $return; 
} 

然后我在$树数组变量和执行这一块代码:

$t3 = $tree; 
$parts = explode('.', $path); 
while (isset($parts[0]) && count($parts) > 1 && isset($t3['children']) && $parts[0] == $t3['name']) { 
    array_shift($parts); 
    for ($i = 0; $i < count($tree['children']) && $tree['children'][$i]['name'] != $parts[0]; $i++); 
    $t3 = $tree['children'][$i]; 
} 

return isset($t3) && count($parts) == 1 && $parts[0] == $t3['name']? $t3['children'] : array(); 

如果此路径不存在最后一行返回由$路径指向的节点(即“base.listener.test”)或空数组。

回答

0

如果我明白你在找什么,你要拨打:

$result = searchTree('test'); 

,并得到搜索数据库为父母?

SELECT p.name 
    FROM tree c 
    INNER JOIN tree p ON p.lft < c.lft AND p.rgt > c.rgt 
    WHERE c.name = 'test' 
    ORDER BY p.lft; 
+0

不,对不起。我解释得很糟糕......(编辑的问题)。 searchTree()返回一个具有相应子树的多维PHP数组。即如果您要求“base.listener.test”,它将返回一个简单的数组,其中包含节点“test”。如果有人要求“测试”,它不会返回任何结果,因为没有称为“测试”的根元素。如果有人要求'base',它会返回一个包含所有基础子元素的数组:[basic,listener [test]] – Ivan

+0

那么,你在寻找一种更好的方式来填充数组吗?或者在不创建数组的情况下使用树的方法? –

+0

一种更好的方式来填充数组,因为我相信我的方法不是很可扩展性(现在我在树100个项目,但我希望有大约10.000) – Ivan