具有最多和最少比较的堆排序输入
Posted
技术标签:
【中文标题】具有最多和最少比较的堆排序输入【英文标题】:heapsort input with most and fewest comparisons 【发布时间】:2014-02-25 14:55:56 【问题描述】:您好,我环顾四周,找不到任何关于这个问题的直接讨论。大多数似乎都涵盖了时间复杂度和大 O 符号。
我想知道堆排序算法的输入顺序是否以及如何影响对输入进行排序所需的比较次数。例如,采用一个按升序(从小到大)排序的堆排序算法......如果我输入一组已经以这种方式排序的整数(升序)与一组输入相比,它需要多少次比较按降序排列(从大到小)?与一组完全随机的相同数字相比怎么样?
public class Heap
// This class should not be instantiated.
private Heap()
/**
* Rearranges the array in ascending order, using the natural order.
*
* @param pq
* the array to be sorted
*/
public static void sort(Comparable[] pq)
int N = pq.length;
for (int k = N / 2; k >= 1; k--)
sink(pq, k, N);
while (N > 1)
exch(pq, 1, N--);
sink(pq, 1, N);
private static void sink(Comparable[] pq, int k, int N)
while (2 * k <= N)
int j = 2 * k;
if (j < N && less(pq, j, j + 1))
j++;
if (!less(pq, k, j))
break;
exch(pq, k, j);
k = j;
private static boolean less(Comparable[] pq, int i, int j)
return pq[i - 1].compareTo(pq[j - 1]) < 0;
private static void exch(Object[] pq, int i, int j)
Object swap = pq[i - 1];
pq[i - 1] = pq[j - 1];
pq[j - 1] = swap;
// is v < w ?
private static boolean less(Comparable v, Comparable w)
return (v.compareTo(w) < 0);
【问题讨论】:
我们可以提供答案,但我相信学习算法的最佳选择是用笔/纸自己用一组数字来完成它。通常,SO 更多的是针对您遇到的问题的特定部分,显示您已经尝试过的内容。 我只是使用修改后的堆排序算法对其进行了研究,但我的结果似乎不正确......我什至不确定如何解释它们。我想出的是,似乎已经以升序或降序方式完美排序的输入似乎具有相同的、最少数量的可能比较......但这似乎并不正确 因此(通常)heapsort 在进入 HeapSort 本身之前会经过Build-Max-Heap
算法。你能展示你的Build-Max-Heap
算法吗?
我刚刚编辑了原始帖子并包含了完整的堆排序算法
【参考方案1】:
堆排序不同于冒泡排序和快速排序,当输入元素以降序/升序方式排序时,不会发生最好和最坏的情况。堆排序的第一步是构建一个堆(通常是最大堆),它可以通过使用 heapify 的“筛选”版本在线性时间 O(n) 内完成,无论初始元素是什么顺序。如果输入已经是堆,则只是节省了交换时间。 通常认为最好和最坏情况的性能都是 O(nlogn)(the heap sort item on wiki 说最好的情况性能可以是 Ω(n),并且有一个关于它的链接),但是大 - O 表示法省略了常数因子和低阶项,因此它们在大 O 表示法中是等价的,但它们可以相差一个常数因子。
例如,我得到给定元素的所有 720 个排列:1,2,3,4,5,6 并使用您的代码对它们进行排序,最小/最大比较次数为 12/17,而顺序分别是 6,1,4,2,3,5/1,4,2,5,6,3。最小/最大交换次数为 8/15,顺序分别为 6,3,5,1,2,4/1,2,3,5,4,6。 My another post 大约是交换的最大数量。
【讨论】:
以上是关于具有最多和最少比较的堆排序输入的主要内容,如果未能解决你的问题,请参考以下文章