【问题标题】:How do I efficiently keep track of the smallest element in a collection?如何有效地跟踪集合中的最小元素?
【发布时间】:2010-09-07 05:34:30
【问题描述】:

编程问题的脉络中:假设有一组可以相互比较和排序的对象。在添加对象并偶尔删除当前最小元素时,跟踪集合中最小元素的最有效方法是什么?

【问题讨论】:

    标签: data-structures collections


    【解决方案1】:

    使用最小堆是最好的方法。

    http://en.wikipedia.org/wiki/Heap_(data_structure)

    它是为这个应用量身定做的。

    【讨论】:

    • 斐波那契堆比最小堆快,它有 O(1) 插入而不是 O(log(n))
    • 我从未听说过斐波那契堆
    • [这最初是我在实施 cmets 之前发布的一个单独的“答案”] 这是我最初的建议,直到我意识到最小堆不是为随机删除元素而设计的,只有最小的一。不管怎样,看来你的回答还是被接受了。
    【解决方案2】:

    如果您需要随机插入和删除,最好的方法可能是排序数组。插入和删除应该是 O(log(n))。

    【讨论】:

      【解决方案3】:

      @Harpreet
      这不是最优的。当一个对象被移除时,erickson 将不得不扫描整个集合以找到新的最小的。

      您想阅读Binary search tree 的内容。 MS 有一个很好的site 来开始这条路。但如果你想深入了解,你可能想买一本像Introduction to algorithms (Cormen, Leiserson, Rivest, Stein) 这样的书。

      【讨论】:

        【解决方案4】:

        对于偶尔的删除,Fibonacci Heap 甚至比最小堆还要快。插入是 O(1),找到最小值也是 O(1)。去除是 O(log(n))

        【讨论】:

          【解决方案5】:

          如果您需要随机插入和移除, 最好的方法可能是排序 大批。插入和删除应该是 O(log(n))。

          是的,但是您需要对每次插入和(可能)每次删除重新排序,正如您所说,这是 O(log(n))。

          使用 Harpreet 提出的解决方案:

          • 一开始你有一个 O(n) 次遍历来找到最小的元素
          • 此后插入的时间为 O(1)(只需要与已知的最小元素进行 1 次比较)
          • 删除将是 O(n),因为您需要重新找到最小的元素(请记住大 O 表示法是最坏的情况)。您还可以通过检查要删除的元素是否是(已知的)最小元素来进行优化,如果不是,则不要进行任何重新检查以找到最小元素。

          所以,这取决于。其中一种算法对于删除很少的插入量大的用例会更好,但另一种算法总体上更一致。我想我会默认使用 Harpreet 的机制,除非我知道最小的数字会经常被删除,因为这暴露了该算法的弱点。

          【讨论】:

          • 只是想指出 big-O 不一定是最坏情况。它只是描述函数渐近行为的符号,它对最坏情况或最好情况一无所知-case 或介于两者之间的任何内容,它仅用于描述您正在查看的任何函数的行为。
          • 事实上,我什至可以说,除非特别说明,否则大 O 符号最常用于描述平均情况,而不是最坏情况。
          【解决方案6】:

          哈普雷特:

          插入将是线性的,因为您必须为插入移动项目。

          这不取决于集合的实现吗?如果它像一个链表,插入将是 O(1),而如果它像一个数组一样实现,它将是线性的,正如你所说的。

          【讨论】:

            【解决方案7】:

            取决于您需要容器支持哪些操作。如果您可能需要在任何给定时间删除 min 元素,min-heap 是最好的,尽管有几个操作很重要(在某些情况下摊销 log(n) 时间)。

            但是,如果您只需要从前/后推/弹出,则可以只使用一个能够为所有操作(包括 findmin)实现摊销恒定时间的 mindeque。您可以通过a scholar.google.com search 了解有关此结构的更多信息。我和一个朋友最近合作开发了一个更容易理解和实现的 mindeque 版本。如果这是您要查找的内容,我可以为您发布详细信息。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多