具有左,右和深度的PHP递归foreach

时间:2019-01-11 14:55:44

标签: php json recursion foreach

我有一个来自geonames.org的json文件,我想使用 php递归foreach 从该文件添加数据。

我只是成功,因为我只是不了解左右深度的概念。深度保存正确。

我的代码是:

public function buildTree($elements, $count = 1, $depth = 0)
    {
        if (isset($elements->geonames)) {
            foreach ($elements->geonames as $element) {
                $left = $count++;

                $elementDB = new \App\Geo();

                $elementDB->id        = $element->geonameId;
                $elementDB->parent_id  = NULL;
                $elementDB->left      = $left;
                $elementDB->right     = $right;
                $elementDB->depth     = $depth;
                $elementDB->name      = $element->name;
                $elementDB->country   = $element->countryCode;
                $elementDB->level     = $element->fcode;
                $elementDB->lat       = $element->lat;
                $elementDB->long      = $element->lng;
                $elementDB->save();

                $elements = $this->getList($element->geonameId, 'element');

                if ($depth < 1) {
                    $this->buildTree($elements, $count, $depth + 1);
                }

                $right = $count++;

                echo "Added element " . $element->name . "\n";
            }
        }
    }

This should happen

3 个答案:

答案 0 :(得分:1)

我假设这里是在制作二叉搜索树。基本上,树是具有根,“常规”节点和叶子的图。

顶部总是有一个单一的根,这是一个特定的节点。

叶子下面没有其他节点,它们是树的“末端”。

常规节点可能有两个子节点,一个较小(左侧),另一个较大(右侧)。这使得像这样:

enter image description here

如您所见,来自根的左子节点的所有节点均小于8。右子节点的所有节点均大于8。这样,当您搜索“ 10”时,您立即知道自己拥有可以遍历根的右子,而无需探索左侧(这意味着更少的处理时间)。

答案 1 :(得分:1)

可能的二进制搜索树搜索算法实现如下:

function buildTree($elements, $left, $right, $needle){
    if ($left > $right) return null;
    $middle = floor(($left + $right) / 2);
    $val = $elements[$middle];
    if ($val === $needle) return $val;
    else if ($val < $needle) return buildTree($elements, $left + 1, $right, $needle);
    else if ($val > $needle) return buildTree($elements, $left, $right + 1, $needle);
}

echo buildTree([1, 2, 3, 4, 5], 0, 5, 4);

您只需要使它适应您的问题

答案 2 :(得分:1)

您似乎想了解其工作原理? 您可以使用递归来处理每个元素。变量$ elements是带有节点的树(或子树)。您的代码必须从左到右浏览树。在每次迭代中,您都要检查$ elements是否具有节点。如果$ elements具有(可能是带有字段的有序数组或结构)节点,则必须处理这些节点。在每次检查期间,您将检测每个节点是否有其他子节点。当您找到具有其他子节点的第一个节点(让我们将其命名为“ A”)时,您必须在下一次迭代递归中进行处理,以处理当前子节点(“ A”)的子节点。
enter image description here

数字表示在左右深度算法中访问节点的顺序。

坦白说,我不明白您添加的内容:

$this->buildTree($elements, $count, $depth + 1);

对于 foreach 中的变量,这是错误的样式重新分配: enter image description here

也许对您来说很有趣When is it practical to use Depth-First Search (DFS) vs Breadth-First Search (BFS)?