【问题标题】:How to store big binary tree如何存储大二叉树
【发布时间】:2011-08-25 05:43:10
【问题描述】:

如何存储大型二叉树(深度约为数千)。 我们试图存储在数据库中,在具有行的表中:elem、parent、left_child、right_child 但是处理这棵树很慢(计算,画出它的一部分)。

您推荐哪种方式? (计算可以在 php 中完成)。可能是将其存储在 XML 或 json(文本文件)或某些矩阵中?

【问题讨论】:

  • 标准 SQL 设置对于这样的结构是出了名的糟糕。表示非常简单,但检索是一个严重的痛苦。不过,Oracle 和 Postgres(?) 通过“先连接”扩展支持递归查询。
  • 使用了什么样的数据库?你尝试过 Redis、MongoDB 吗?
  • 一棵典型的树有多少个节点?一棵 1000 层深的二叉树可能包含 2^1000 个节点 - 这是一个非常大的数字(即使对于 DBMS 也是如此)。
  • 2 OZ_,不,我们使用关系数据库(postgres)。
  • 2 NealB,是的,树可能有 1000 个级别...

标签: php binary-tree


【解决方案1】:

我使用如下结构

id  parent  tree    slug    name    path    children
1   0       1       root    Root    ||          |5|
2   7       1       child-1 Child 1 |1-5-8-7|   |3|

查询大深度树非常容易,因为查询是线性的。 每行数据多一点,但这样会更快。

例如,您可以通过以下简单查询获得整个子树:

$sql = 'SELECT * FROM `'.$this->_table_name.'` WHERE 
            `path` LIKE "%-:parent-%"
            OR `path` LIKE "%|:parent-%"
            OR `path` LIKE "%-:parent|%"
            OR `path` LIKE "%|:parent|%"';

$result = $this->_db->custom_query($sql, array('parent' => $root->id));

然后通过一个简单的函数构建深度数组:

private function _build_tree(Node $root, $data)
    {
        $mapped_node = array(
            'node' => $root,
            'subnodes' => array()
        );

        if ( !empty($root->children) )
        {
            foreach( $root->children as $child )
            {
                if ( array_key_exists($child, $data) )
                {
                    $mapped_node['subnodes'][] = $this->_build_tree($data[$child], $data);
                }
            }
        }

        return $mapped_node;
    }

注意!当我取回子项和路径列时,我将它们拆分为数组以便 PHP 能够更好地使用它们。

【讨论】:

    【解决方案2】:

    似乎最好按照您的建议写入 XML 之类的东西。转换为 XML,然后在您想要重新加载时返回,这将非常简单。

    【讨论】:

    • 一切都可以存储在 XML 中,但是有太多的选择:嵌套元素或引用 id 的属性,甚至是包含一些二进制格式的 CDATA 部分...... ;-)
    【解决方案3】:

    您可以使用数组或其他线性存储(例如关系 id->节点值),每个节点 x 都有子节点 2*x 和 2*x+1。如果树不平衡,问题可能是有未使用的 id。

    示例:

        2---4---8
       /   \   \9
    1--     5---10
       \       \11
        3---6---12
           \   \13
            7---14
               \15
    

    【讨论】:

    • 如果你想显示一个子树,只需计算所需的 id 并批量查找值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多