Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中,从平面邻接列表开始计算嵌套集的左右值?_Php_Nested Sets_Adjacency List - Fatal编程技术网

在PHP中,从平面邻接列表开始计算嵌套集的左右值?

在PHP中,从平面邻接列表开始计算嵌套集的左右值?,php,nested-sets,adjacency-list,Php,Nested Sets,Adjacency List,我正在尝试仅使用PHP将邻接列表转换为嵌套树。我只需要计算左右值:level、parent\u id和root\u id可用: $adj = array( 0 => array( 'id' => 100, 'name' => 'ELECTRONICS', 'level' => 0, 'parent_id' => null, 'root_id' => 100, ),

我正在尝试仅使用PHP将邻接列表转换为嵌套树。我只需要计算左右值:
level
parent\u id
root\u id
可用:

$adj = array(
    0 => array(
        'id' => 100,
        'name' => 'ELECTRONICS',
        'level' => 0,
        'parent_id' => null,
        'root_id' => 100,
    ),
    1 => array(
        'id' => 101,
        'name' => 'SPARE PARTS',
        'level' => 1,
        'parent_id' => 100,
        'root_id' => 100,
    ),
    2 => array(
        'id' => 102,
        'name' => 'FANS',
        'level' => 2,
        'parent_id' => 101,
        'root_id' => 100,
    ),
    3 => array(
        'id' => 103,
        'name' => 'KEYS',
        'level' => 2,
        'parent_id' => 101,
        'root_id' => 100,
    ),
    4 => array (
        'id' => 200,
        'name' => 'CONSUMER ELECTRONICS',
        'level' => 0,
        'parent_id' => null,
        'root_id' =>  200,
    ),
    5 => array(
        'id' => 201,
        'name' => 'KITCHEN',
        'level' => 1,
        'parent_id' => 200,
        'root_id' => 200,
    ),
    6 => array(
        'id' => 202,
        'name' => 'FRIDGE',
        'level' => 2,
        'parent_id' => 201,
        'root_id' => 200,
    ),
);
我已经搜索了很多,我不得不承认我不擅长递归,也许我把这篇文章中的引用传递搞砸了

我的不工作试验:只有根得到左和右值(似乎计算得很好):


最好先从平面阵列构建嵌套结构,然后再分配正确的节点(左/右)。同样在性能方面

为了从平面数组快速查找,我首先将
$adj
列表转换为一个带有
$id=>$val
的数组。只有在最后,从根叶中删除那些有父叶的,这样你才可以在开始时线性地访问它们,就像需要的那样

$mapped["leafs"] = [];
foreach ($adj as $val) {
    $mapped["leafs"][$val["id"]] = $val;
}
foreach ($mapped["leafs"] as $id => &$n) {
    if ($n["parent_id"] !== null) {
        $mapped["leafs"][$n["parent_id"]]["leafs"][$id] = &$n;
    }
}
$cleanup = function (&$n) use (&$cleanup) {
    if (!isset($n["leafs"])) {
        return;
    }

    ksort($n["leafs"]);

    /* now, if you assume to always have maximum two nodes... if you want more, just use leafs and remove that below... */
    $n["left"] = reset($n["leafs"]);
    if (count($n["leafs"]) > 1) {
        $n["right"] = end($n["leafs"]);
    }
    unset($n["leafs"]);
};
foreach ($mapped["leafs"] as $id => &$n) {
    if ($n["parent_id"] !== null) {
        unset($mapped["leafs"][$id]);
    }
    $cleanup($n);
}
$cleanup($mapped);

(注意:我假设parent_id为null也是对root的有效检查,尤其是在数组查找时,它们无论如何都不能为null。)

我真的不确定左值和右值是什么意思?可以给我一些想要的输出示例吗?在嵌套集模型中,每个节点都有一个左值和一个右值。左总是比右少。对于每个节点,左值始终小于子代左/右值,而右值大于子代左/右值。对于叶,左=右+1保持不变。我将添加输出的外观。更多信息:啊,好吧,我想我明白你的问题了…让我写一个答案;-)
$mapped["leafs"] = [];
foreach ($adj as $val) {
    $mapped["leafs"][$val["id"]] = $val;
}
foreach ($mapped["leafs"] as $id => &$n) {
    if ($n["parent_id"] !== null) {
        $mapped["leafs"][$n["parent_id"]]["leafs"][$id] = &$n;
    }
}
$cleanup = function (&$n) use (&$cleanup) {
    if (!isset($n["leafs"])) {
        return;
    }

    ksort($n["leafs"]);

    /* now, if you assume to always have maximum two nodes... if you want more, just use leafs and remove that below... */
    $n["left"] = reset($n["leafs"]);
    if (count($n["leafs"]) > 1) {
        $n["right"] = end($n["leafs"]);
    }
    unset($n["leafs"]);
};
foreach ($mapped["leafs"] as $id => &$n) {
    if ($n["parent_id"] !== null) {
        unset($mapped["leafs"][$id]);
    }
    $cleanup($n);
}
$cleanup($mapped);