在修改preorder树遍历路径遍历、路径、preorder

2023-09-11 06:19:03 作者:随心随缘

我已经实现了一个改进的preorder树遍历这里。我的树是这样的:

I've implemented a Modified Preorder Tree Traversal as explained here. My tree is something like this:

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

一切正常,但现在我试图执行一个PHP的搜索功能根据在路径上,它是这样的:

Everything is ok, but now I tried to implement a PHP search function based on a path, it is, something like this:

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

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

It means that searchTree returns a subtree based on the path given. If the path doesn't exists it will return an empty array.

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

My current implementation is a recycled function that loads the tree into a PHP array and then it splits the path and walks through the array. It seems a non-scalable implementation... Any better implementation (perhaps using a mySQL query?).

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

My current implementation is like this. First I get the whole tree (SELECT * FROM tree) and then I execute this function to make a multidimensional array from this data:

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;
}

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

Then I have an array in $tree variable and execute this piece of code:

$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();

最后一行返回由$ PATH指出的节点(即base.listener.test),或者如果这个路径不存在一个空数组。

The last line returns the node pointed by the $path (i.e. 'base.listener.test') or an empty array if this path doesn't exists.

推荐答案

如果我知道你在寻找什么,你要调用:

If I understand what you're looking for, you want to call:

$result = searchTree('test');

和获得搜索数据库为父母?

and get search the database for the parents?

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;