我一直在使用矢量在C++中实现一个堆。由于我必须轻松访问节点(2n,2n + 1)的子节点,因此我必须从索引1开始。这是正确的方法吗?根据我的实现,在第零个位置总是有一个虚拟元素。索引:使用数组/矢量实现树数据结构
回答
你的方式有效。另外,您可以在索引0
有根,并在2n+1
和2n+2
或者等价地,按照问题中描述的所有数学(基础1),但使用自定义运算符[],从其索引中减去1。 – Steve314 2010-09-20 10:46:46
有孩子虽然这可以很好地用于堆,你最终使用一个巨大的其他树的数据结构冗余内存量不一定有一个全面和完整的二叉树。例如,这意味着如果您有一个包含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个级别,每个级别的节点数量是其父级级别的两倍(因为除底部的节点外,每个节点只有两个孩子 - 从来没有一个)。 A binary heap是一个binary tree(但不是二进制搜索树),它总是按定义完成的,所以由OP概述的基于数组的实现不会产生任何实际的内存开销。对于堆来说,这是在代码中实现它的最佳方式。 OTOH,大多数其他二叉树(特别是二叉搜索树)不保证是完整的。所以试图使用这种方法需要O(2 ^深度)的内存,其中深度可以与n一样大,在链接实现中我们只需要O(n)内存。
所以我的回答是:是的,这是堆的最佳方式。只是不要尝试用于其他二叉树(除非你确定它们将始终完整)。
- 1. 实现树型数据结构
- 2. Java树数据结构实现
- 3. 如何印刷使用类实现的树数据结构?
- 4. 如何使用树状数据结构高效地实现unordered_map?
- 5. 元组索引的数据结构
- 6. 数据库文件结构和索引及实现
- 7. 如何矢量化使用索引数组获取numpy数组的子数组
- 8. 树数据结构
- 9. 用ruby实现树和其他数据结构
- 10. 以树结构搜索JSON数据
- 11. 使用C5集合树数据结构
- 12. 实现树状结构UITableview
- 13. 实现图树的最佳数据库结构
- 14. 在java中实现它们的游戏树和数据结构?
- 15. 在FFI结构中索引数组struct
- 16. 使用LINQ从数据库检索树结构
- 17. 矢量结构
- 18. “排序”树数据结构
- 19. 结构java树型数据
- 20. 树像数据结构
- 21. 树数据结构addnode
- 22. Rails 3树数据结构
- 23. iPhone树型数据结构
- 24. 树的数据结构
- 25. 树数据结构和数据
- 26. 基于索引的数据结构
- 27. 字符串索引的数据结构?
- 28. 搜索引擎的数据结构?
- 29. matlab:结构数据和多级索引
- 30. 文档词索引数据库结构?
为什么不使用make_heap()(http://www.sgi.com/tech/stl/make_heap.html)呢? – 2010-09-20 10:23:47
因为这是一个很好的学习练习? – 2010-09-20 10:34:37