开发者

Path in a Modified Preorder Tree Traversal

开发者 https://www.devze.com 2023-04-02 01:53 出处:网络
I\'ve implemented a Modified Preorder Tree Traversal as explained here. My tree is something like this:

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 | 
+-------+-----------+-----+-----+

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}

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

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?).

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

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

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

精彩评论

暂无评论...
验证码 换一张
取 消