在哪些情况下我们使用heapsort?

时间:2013-08-10 15:31:39

标签: c sorting heapsort

在哪种情况下可以使用堆排序?我们知道,堆排序的复杂性为lg(n)。但它的使用频率远低于快速和合并排序。那么我们什么时候才能准确地使用这种堆排序呢?它有什么缺点?

3 个答案:

答案 0 :(得分:1)

Heapsort的特征

  • O(nlogn)时间最佳,平均,最差情况
  • O(1)额外记忆

在何处使用?

  • 保证O(nlogn)性能。当你不一定需要非常快的性能,但保证O(nlogn)性能(例如在游戏中),因为Quicksort的O(n ^ 2)可能会很痛苦。为什么不使用Mergesort呢?因为它需要额外的O(n)内存。
  • 避免Quicksort最糟糕的情况。 C ++的std::sort例程通常使用名为Introsort的Quicksort变体,如果Quicksort递归过深,它会使用Heapsort对当前分区进行排序,表明最坏的情况已经发生。
  • 部分排序的数组,即使突然停止。如果Heapsort以某种方式突然停止,我们会得到一个部分排序的数组。可能有用,谁知道?

<强>缺点

  • 与Quicksort相比相对较慢
  • 缓存效率低下
  • 不稳定
  • 不是真正的自适应(如果给出有些排序的数组,则不会更快)

答案 1 :(得分:0)

根据wikipedia article for sorting algorithms,似乎Heapsort和Mergesort在最佳,平均和最差情况下都具有相同的时间复杂度O(n log n)

Quicksort的缺点是O(n2) (a)的最坏情况时间复杂度。

Mergesort的缺点是其内存复杂度为O(n),而Heapsort为O(1)。另一方面,Mergesort是一个稳定的排序,而Heapsort则不是。

因此,基于此,如果我不关心排序的稳定性,我会选择Heapsort优先于Mergesort,以便最小化内存使用。如果需要稳定性,我会选择MergeSort。


或者,更准确地说,如果我有大量数据需要排序,而且我必须编写自己的算法来编写,我会这样做。对于绝大多数情况,两者之间的差异是无关紧要的,直到您的数据集变得庞大。

事实上,我甚至在没有提供其他类型的实际生产环境中使用冒泡排序,因为:

  • 它非常容易编写(甚至是优化版本);
  • 如果数据具有某些属性(在添加几个项目之前已经大部分已经排序的小型数据集或数据集),它就足够有效了。

goto和多个回归点一样,即使看似糟糕的算法也有它们的位置: - )


(a)并且,在您想知道为什么C使用效率较低的算法之前,它(不一定)。尽管有qsort名称,但没有任何授权它使用Quicksort - 这是一个常见的误解。它可能会使用其他算法之一。

答案 2 :(得分:0)

请注意,堆排序的运行时复杂度与O(n log n)相同,无论数组是否已按升序或降序部分排序。

请参阅以下链接,以进一步澄清大O计算: https://ita.skanev.com/06/04/03.html