【问题标题】:Implementation of Heap (ADT) using Array Vs. LinkedList使用 Array Vs 实现堆 (ADT)。链表
【发布时间】:2016-04-15 12:32:02
【问题描述】:

在我的数据结构课程中,我需要实现一个具有以下时间复杂度要求的二进制堆:

  • 求最大值 - O(1)
  • 插入 - O(lg n)
  • 删除最大值 - O(lg n)

现在我想通过以下方式使用数组来实现这一点:堆的根在 Arr[1](第一个索引)中。 Arr[i] 的孩子在 Arr[2i] 和 Arr[2i+1] 中(2 个孩子)。 通过这个实现,我将在 O(1) 中找到 Max,在 O(n) 中删除 Max 并在 O(lg n) 中插入,但有一个例外 - 如果我需要在数组已满时插入,我将不得不调整数组的大小并且将“花费”我 O(n),因此插入所有边缘情况的总成本将是 O(n) 而不是 O(log n)。

是否有其他实现方式可以满足所有复杂性要求? 我想也许可以尝试使用 LinkedList 而不是数组来实现,但插入仍然是 O(n)。非常欢迎任何有关实施的建议。

【问题讨论】:

    标签: arrays linked-list heap time-complexity abstract-data-type


    【解决方案1】:

    您的实现可以满足要求。我假设当您说删除最大值将占用 O(n) 时,您认为您需要将整个数组移动到一个位置?在这种情况下,您实际上需要做的是让下一个最大的元素像他们所说的那样“游”到顶部。这只需要 O(lgn) 时间。

    而且调整大小不会经常发生,所以 amortized 运行时仍然是 O(lgn)。 See here.

    【讨论】:

    • 谢谢你,其实我的意思是通过使用你提到的“游泳”技术来写“删除最大值”是 O(log n)。我的问题是插入 - 我知道摊销运行时间是 O(log n) 但我需要最坏情况下的运行时间是 O(log n) 并且这让我认为也许我不应该使用数组来实现这个堆但以不同的方式......
    • 好的,我明白了。从那篇维基百科文章中得出的一个想法摊销分析的动机是,查看每个操作的最坏情况运行时间可能过于悲观。我认为你有正确的实现。见this powerpoint。您当前的实现仍被认为是 O(lgn)。
    • 好的。所以我会像这样探索地离开实现。谢谢
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 2019-03-04
    • 2020-01-16
    相关资源
    最近更新 更多