简体   繁体   English

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

[英]how to preview the adjacency list tree by using for loops (Non-recursive solution)

I store a tree in MySQL database by using the adjacency list method 我使用邻接表方法将树存储在MySQL数据库中

when I want to preview the tree, PHP retrieves the whole tree from the database and preview it using recursion. 当我想预览树时,PHP从数据库中检索整个树并使用递归预览。

But iterations is better than recursion in performance, so I want to populate the tree using the for loops to achieve better performance. 但是迭代在性能上优于递归,因此我想使用for循环填充树以获得更好的性能。

I do not want to use any MySQL functions or methods or triggers, I just want to populate the tree by using iterations (for loops) 我不想使用任何MySQL函数或方法或触发器,我只想通过使用迭代(用于循环)来填充树

I stumbled on this old unanswered question, while searching for a link to aide in answering a similar question on IRC. 在寻找有关在IRC上回答类似问题的助手的链接时,我偶然发现了这个古老的悬而未决的问题。

This is a rough example showing how to build a list of paths from an adjacency list, it requires the data to be sorted by the 'parent' then 'id', this could easily be translated to an SQL SELECT with an ORDER BY parent, id clause: 这是一个粗略的示例,展示了如何从邻接列表构建路径列表,它要求数据先按“父”然后按“ id”进行排序,然后可以很容易地将其转换为带有ORDER BY parent, id的SQL 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 ])));
}

Output: 输出:

1 => 1
2 => 1/2
3 => 1/2/3
4 => 1/2/3/4
5 => 5
6 => 5/6
7 => 5/7
8 => 5/7/8
9 => 5/7/8/9
10 => 5/10
11 => 11
12 => 5/12
13 => 5/13
14 => 11/14
15 => 5/13/15
16 => 1/16
17 => 5/13/15/17

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM