【问题标题】:how to preview the adjacency list tree by using for loops (Non-recursive solution)如何使用for循环预览邻接列表树(非递归解决方案)
【发布时间】:2012-02-23 20:52:20
【问题描述】:

我使用邻接表方法在 MySQL 数据库中存储一棵树

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

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

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

【问题讨论】:

  • 为什么迭代对性能更好?
  • 发布一些代码来说明你的意思会有帮助
  • 如果您知道树的确切尺寸,您可以使用 for 循环,但如果树的尺寸发生变化,那么您将不得不使用递归来获取整个树。
  • 为什么迭代对性能更好? sitepoint.com/hierarchical-data-database 大多数语言都不是为递归函数设计的。对于每个节点,该函数启动另一个自身的实例。因此,对于具有四个级别的树,您将同时运行该函数的四个实例。由于每个函数都占用一块内存并需要一些时间来启动,因此递归在应用于大树时非常慢。

标签: php mysql tree adjacency-list


【解决方案1】:

我在寻找一个链接以帮助回答 IRC 上的类似问题时偶然发现了这个老问题。

这是一个粗略的示例,展示了如何从邻接列表构建路径列表,它要求数据先按“父”排序,然后按“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 ])));
}

输出:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多