【问题标题】:KDTree implementation as single array / without nodesKDTree 实现为单个数组/无节点
【发布时间】:2013-10-07 22:27:13
【问题描述】:

所以对于一个项目,我已经实现了一个平衡的 KD-Tree 和 k-最近邻搜索算法,它是作为标准树的“传统”方式 - 即我有如下节点结构

struct KDNode{
    int level; //used for x,y,z axis splitting
    Point pos;
    KDNode *left, *right; //Child nodes
}

...然后将树作为实际的树数据结构存储在内存中。但是,我最近听说可以将 KD-Tree 作为一个大数组存储在内存中,而无需创建任何节点对象,而且这种构造方法在内存和时间性能方面会更有效。

但是,我完全不确定这样的构造将如何工作,也无法在网上找到任何详细说明我将如何以这种方式实现 KD-Tree 的内容。

所以我的问题是,如何在不使用节点的情况下将 KD-Tree 实现为一维数组?

【问题讨论】:

  • 由于 KDTrees 是二进制的,请看一下:en.wikipedia.org/wiki/Binary_tree#Arrays
  • 可以创建一个 std::vector 节点;然后,您可以使用 nth_element 查找中值等。左右可以直接指向向量中的子节点(如果您的数据集是静态的,您不希望向量调整大小)。无需自己分配任何内存。

标签: arrays algorithm data-structures graphics tree


【解决方案1】:

好吧,我可以看到如何在单个数组中实现它。但它需要一个相当密集且平衡良好的 kd-tree。如果你的树是稀疏的,它可以用一个数组来实现,但在空间方面会相当浪费。

您可以使用他们用来在数组中实现堆的相同技术。有一个公式可以使用项目当前索引查找项目的子项,更多信息 here 和 here。公式是 2*index+1 表示左孩子,2*index+2 表示右孩子。

这种“堆作为数组”可以应用于任何二叉树数据结构,但它对堆特别有用,因为您知道数组将被密集填充。

节点中有索引值的完整二叉树:

               [0]
      [1]                [2]
  [3]     [4]       [5]       [6]  
[7] [8] [9] [10] [11] [12] [13] [14]

数组中的相同表示: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]

如果您在 [4] 并想找到它的孩子;它的左孩子是 (2*4+1) 9,它的右孩子是 (2*4+2) 10。

【讨论】:

  • 谢谢!这是有道理的。
【解决方案2】:

您可以通过空间填充曲线来减少维度,但需要付出一些代价。使用四键搜索最近邻。

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多