【问题标题】:Most performant way to find all the leaf nodes in a tree data structure在树数据结构中查找所有叶节点的最高效方法
【发布时间】:2017-10-07 18:09:18
【问题描述】:

我有一个树数据结构,其中每个节点可以有任意数量的子节点,并且树可以是任意高度。获取树中所有叶节点的最佳方法是什么?是否有可能比只遍历树中的每条路径直到我碰到叶子节点做得更好?

实际上,树的最大深度通常为 5 左右,树中的每个节点将有大约 10 个子节点。

我对其他类型的数据结构或特殊树持开放态度,这些数据结构或特殊树会使叶节点特别优化。

我正在使用 javascript,但实际上只是在寻找一般建议,任何语言等。

谢谢!

【问题讨论】:

    标签: algorithm performance optimization tree


    【解决方案1】:

    内存布局对于最佳检索至关重要,因此子列表应该是连续的而不是链表,节点应该按检索顺序依次放置。

    你的树越静态,布局就越好。

    多合一布局

    • 完全有序的一个数组

    • 专业版

      • 内存可以流式传输以获得最大吞吐量(硬件预取)
      • 没有不需要的页面查找
      • 可以正常查找
      • 没有额外的内存来创建链表。
      • 内部节点使用偏移量来查找相对于自身的子节点
    • 骗子

      • 插入/删除可能很麻烦
      • 插入/删除 O(N)
      • 插入可能会导致调整数组大小,从而导致复制成本高昂

    两个数组布局

    • 一个用于内部节点的数组
    • 一个叶子数组
    • 内部节点指向叶子

    • 专业版

      • 叶节点可以以最大吞吐量进行流式传输(如果您主要只对叶感兴趣,这可能是最佳布局)。
      • 没有不需要的页面查找
      • 可以进行间接查找
    • 骗子

      • 如果所有叶子都是有序的,插入/删除可能很麻烦
      • 如果叶子是无序插入很容易,只需在末尾添加即可。
      • 如果不允许墓碑删除无序叶子也是一个问题,因为最后一个叶子必须移回并且内部节点需要修复。 (通过进一步的间接,这也可以修复,参见 slot-map)
      • 调整两者之一的大小可能会导致较大的副本,但小于一体机,因为它们可以独立完成。

    数组数组(动态大小,C++ 向量向量)

    • 使用连续数组来引用每个节点的子节点
    • 专业版
      • 遍历每个子列表很快
      • 每个子数组都可以独立调整大小
    • 骗局
      • 虽然消除了链表子项的大部分额外工作,但单个列表分散在所有其他数据中,使得查找需要额外的时间。
      • 插入可能会导致数组的大小调整和复制。

    【讨论】:

      【解决方案2】:

      查找树的叶子是O(n),这对于树来说是最优的,因为您必须查看O(n) 的位置来检索所有n 的东西,以及沿途的分支节点。恒定开销是分支节点。

      如果我们增加分支因子,例如让每个分支有 32 个子节点而不是 2 个,我们显着减少了开销节点的数量,这可能会使遍历速度更快。

      如果我们跳过一个分支,我们不包括该分支中的值,所以我们必须查看所有分支。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 2013-01-17
        • 2015-06-16
        • 1970-01-01
        相关资源
        最近更新 更多