为什么堆而不是排序的容器

时间:2013-10-31 04:38:53

标签: c++ algorithm sorting

我正在研究c ++ stl算法,并且正在尝试理解堆栈算法(make_heap,sort_heap,push_heap等)。我理解它创建的二叉树以及如何有效地在任何给定时间找到最高优先级项目。我不清楚这是否比维护一个排序容器更好,其中最高价值的项目可以简单地从顶部弹出。

以下是比较,我认为:

对于堆:

  • 创建堆:make_heap: O(nlogn) ...错误!为O(n)
  • 插入:push_heap: O(登录)
  • 删除最高:pop_heap: O(登录)
  • 获取排序列表:sort_heap: O(nlogn)

对于已排序的容器:

  • 初始排序:sort() O(nlogn)
  • 插入:?的 O(logn)时间
  • 删除最高:pop 常量
  • 获取排序列表:已排序常量

插入需要找到具有相同值的元素或值的任一侧的两个元素。在排序列表中,这应该是O(logn)。我还不知道一个特定的算法会做到这一点。

无论如何,我错过了什么?从我上面的分析看来,只是维护一个已排序的容器在所有情况下都不会更糟,而在某些情况下会更好。

谢谢!


编辑:

我想指出这一点,所以没有人读到这个并且被我的问题搞糊涂了。正如里奇指出的那样,我错误地认为make_heap的复杂性。我最初认为它是O(n log n),而是它的O(n)。对我来说,这种差异解释了为什么make_heap比简单地维护一个排序列表更好。

1 个答案:

答案 0 :(得分:3)

make_heap为O(n),而不是O(n log n)。对于大型数据集,它可以比排序快得多。

O(log n)操作(push和remove_min)可能只比平衡二叉树实现快一点,但它们的存储开销要低很多,这也提高了它们的缓存友好性。对于小对象,如整数,堆使用std :: set使用的内存的四分之一。