以最高效的方式查找树数据结构中的所有叶节点

时间:2017-10-07 18:09:19

标签: algorithm performance optimization tree

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

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

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

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

谢谢!

2 个答案:

答案 0 :(得分:1)

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

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

一体化布局

  • 所有在一个阵列中完全订购

    • 内存可以流式传输以获得最大吞吐量(硬件预取)
    • 没有不必要的页面查找
    • 可以进行正常查找
    • 没有额外的内存来制作链表。
    • 内部节点使用offset来查找相对于自身的子项
  • N

    • 插入/删除可能很麻烦
    • 插入/删除O(N)
    • insert可能会导致数组调整大小,从而导致代价高昂的副本

两个数组布局

  • 内部节点的一个数组
  • 一个叶子阵列
  • 内部节点指向叶子

  • 专业

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

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

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

  • 使用连续数组引用每个节点的子节点
    • 快速浏览每个子列表
    • 每个子数组可以独立调整大小
  • 精读
    • 在删除链接列表子项的大量额外工作时,各个列表分散在所有其他数据中,使查找花费额外的时间。
    • insert可能会导致调整大小和复制数组。

答案 1 :(得分:0)

查找树的叶子是O(n),这对于树来说是最佳的,因为您必须查看O(n)个位置以检索所有n个东西,以及沿着分支节点方式。常量开销是分支节点。

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

如果我们跳过分支,我们不会在该分支中包含值,所以我们必须查看所有分支。