如何使用for循环预览邻接列表树(非递归解决方案)

时间:2012-02-23 20:52:20

标签: php mysql tree adjacency-list

我使用邻接列表方法

在MySQL数据库中存储树

当我想要预览树时,PHP从数据库中检索整个树并使用递归进行预览。

但是迭代比性能递归更好,所以我想使用for循环填充树以获得更好的性能。

我不想使用任何MySQL函数或方法或触发器,我只想使用迭代填充树(for循环)

1 个答案:

答案 0 :(得分:0)

我偶然发现了这个未经回答的问题,同时在IRC上寻找助手回答类似问题的链接。

这是一个粗略的例子,展示了如何从邻接列表构建路径列表,它要求数据按“父”然后“id”排序,这可以很容易地转换为SQL {{1}使用SELECT子句:

ORDER BY parent, id

输出:

<?php
$arr = [
    ['id' => 1, 'parent' => 0],
    ['id' => 2, 'parent' => 1],
    ['id' => 3, 'parent' => 2], 
    ['id' => 4, 'parent' => 3], 
    ['id' => 5, 'parent' => 0],
    ['id' => 6, 'parent' => 5],
    ['id' => 7, 'parent' => 5], 
    ['id' => 8, 'parent' => 7],
    ['id' => 9, 'parent' => 8],
    ['id' => 10, 'parent' => 5],
    ['id' => 11, 'parent' => 0],
    ['id' => 12, 'parent' => 5],
    ['id' => 13, 'parent' => 5],
    ['id' => 14, 'parent' => 11],
    ['id' => 15, 'parent' => 13],
    ['id' => 16, 'parent' => 1],
    ['id' => 17, 'parent' => 15],
];

usort($arr, function($a, $b) { return $a['parent'] - $b['parent']?: $a['id'] - $b['id']; });

$paths = [];
foreach($arr as $current) {
    if($current['parent'] > 0) {
        $paths[ $current['id'] ] = array_merge($paths[ $current['parent'] ], [ $current['parent'] ]);
    } else {
        $paths[ $current['id'] ] = [];
    }
}

ksort($paths);
foreach($paths as $k => $v) {
    printf("%s => %s\n", $k, implode('/', array_merge($v, [ $k ])));
}