【问题标题】:Why would one use a heap over a self balancing binary search tree?为什么要在自平衡二叉搜索树上使用堆?
【发布时间】:2015-06-08 15:29:01
【问题描述】:

堆的用途是什么?无论堆可以做什么,也可以通过像 AVL 树这样的自平衡二叉搜索树来完成。堆最常见的用途是在 O(1) 时间(始终是根)内找到最小(或最大)元素。通过维护指向最小(或最大)元素的指针,在构建 AVL 树时也可以包含此功能,并且可以在 O(1) 时间内回答最小/最大查询。

我能想到的与 AVL 树相比,堆的唯一好处是 AVL 树由于指针而使用更多的内存。与 AVL 树相比,使用堆还有其他优势/功能吗?

【问题讨论】:

    标签: data-structures tree heap binary-search-tree avl-tree


    【解决方案1】:

    可能有更好的插入和合并时间。这实际上取决于堆的类型,但通常它们远没有 AVL 严格,因为它们不必担心每次操作后的自动平衡。

    堆只是保证所有节点在整个堆中都遵循相同的排序方式。当然还有更严格的堆,比如二叉堆,由于排序更重要,因此插入和合并更加困难,但情况并非总是如此。

    例如,斐波那契堆的插入和合并时间将是 O(1) 与 AVL 的 O(log n)

    与堆相比,构建完整的 AVL 也更加困难。

    当我们只想快速访问最小和最大项目而不关心其他元素的完美排序时,我们通常使用堆。通过快速插入,我们可以快速处理许多元素,并且始终将注意力集中在最重要(或最不重要)的元素上。

    【讨论】:

      【解决方案2】:

      当你说自平衡二叉树比堆可以做更多的事情并且堆使用更少的指针空间时,你是对的。以下是一些额外的注意事项:

      • 与 AVL 树相比,二叉堆实现所需的代码要少得多。这使得编码、调试和修改变得更加容易。

      • AVL 树使用一个对象容器和每个存储的数据项两个指针。二进制堆对每个存储的数据项使用零开销 - 它全部打包到一个数组中。

      【讨论】:

        【解决方案3】:

        主要原因是二叉堆实际上实现为数组,而不是树(树是一个比喻,实际实现是一个数组,其中索引为i的元素的子元素是索引为@987654324的元素@ 和 2i+2)。数组在空间和时间上都比树更有效(在常量方面) - 由于locality of reference,使数据结构的缓存效率更高,这通常会产生更好的常量。

        此外,initializing a binary heapn 元素需要 O(n) 时间,而对 BST 执行相同操作需要 O(nlogn) 时间。

        【讨论】:

        • 您可以使用指针或数组来实现堆。除非您谈论特定语言的库,否则没有“实际实现”。
        • @EricHotinger 我说的是它是如何在所有实际案例中实际实现的。你不能对 BST (AFAIK) 做同样的事情,因为你不能强迫它成为几乎完整的树。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-13
        相关资源
        最近更新 更多