简体   繁体   中英

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

when I want to preview the tree, PHP retrieves the whole tree from the database and preview it using recursion.

But iterations is better than recursion in performance, so I want to populate the tree using the for loops to achieve better performance.

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)

I stumbled on this old unanswered question, while searching for a link to aide in answering a similar question on 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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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