索引:使用数组/向量实现树数据结构

时间:2010-09-20 10:21:21

标签: c++ data-structures

我一直在使用向量在C ++中实现堆。因为我必须轻松访问节点(2n,2n + 1)的子节点,所以我必须从索引1开始。这是正确的方法吗?根据我的实现,在第零个位置总是有一个虚拟元素。

2 个答案:

答案 0 :(得分:4)

你的方式有效。或者,您可以在索引0处拥有root,并在2n+12n+2生成子项

答案 1 :(得分:2)

虽然这适用于堆,但最终会为其他树数据结构使用大量冗余内存,而这些结构不一定具有完整且完整的二叉树。例如,这意味着如果你有一个20个节点的深度为5的二进制搜索树,你最终必须使用2 ^ 5 = 32而不是20的数组。现在想象一下你是否需要一个25个节点的树深度为22.您最终使用了大量的4194304,而您可以使用链接表示来存储25个节点。

您仍然可以使用数组而不会产生这样的内存命中。只需将一大块内存分配为数组,并使用数组索引作为指向子代的指针。

因此,你在哪里

node.left = (node.index*2)
node.right = (node.index*2+1)

您只需使用

node.left = <index of left child>
node.right = <index of right child>

或者,如果您的语言支持,您可以只使用指针/引用而不是整数索引。

修改

对于每个人来说,完整的二叉搜索树占用O(2 ^ d)内存可能并不明显。有d个级别,每个级别的节点数量是其父级所在级别的两倍(因为除了底部的节点之外的每个节点都有两个子节点 - 从不一个)。 binary heapbinary tree(但不是二进制搜索树),根据定义总是完整的,因此OP概述的基于数组的实现不会产生任何实际的内存开销。对于堆,这是在代码中实现它的最佳方式。 OTOH,大多数其他二叉树(尤其是二进制搜索树)不保证是完整的。因此,尝试使用这种方法需要O(2 ^深度)内存,其中深度可以与n一样大,其中我们在链接实现中只需要O(n)内存。

所以我的回答是:是的,这是堆的最佳方式。只是不要为其他二叉树尝试它(除非你确定它们总是完整的)。