当前位置: 华文星空 > 知识

为什么在平均情况下快速排序比堆排序要优秀?

2014-05-22知识

对于这个问题,我们主要可以从工作机理、原理分析以及复杂度比较三个角度去理解。

1 工作机理

设有任意一数组, C = [x1, x2, x3, …, Xn],

目标: 将其从大到小进行排序;就快排和堆排两个算法的过程作出如下分析:

  • 快速排序过程:
  • S1. 在数组中定义两个指针 , p1, p2; 指针p1是从左向右,p2是从右向左。

    S2. 取数组的第一个元素作为基准(理论上可以取任意一个),利用上述两个指针找出比基准小的放在左边,比基准大的放在右边。

    S3. 在第二步中调整完后,基准值会将原数组分成三部分,[比基准小的数],[基准], [比基准大的数]

    S4. 把S3中的 [比基准小的数], [比基准大的数] 代入S2 ;

  • 堆排序过程:
  • S1. 初始化大顶堆;(该结构上是一颗完全二叉树,该过程又叫构造堆过程。)

    S2. 将最后一个元素与第一个元素互换;

    S3. 重新调整至大顶堆,代入S1;

    2 原理分析

    (1) 快速排序原理

    其实就是通过不断产生新的基准值,将原数组不断地划分成两部分,然后进行大小调整。这样做的原因是因为它在迭代过程中会产生一个不可控的序列,就是[比基准小的数], [比基准大的数]。我们只知道这两个子数组里面的元素比基准大或小,实质上该数组内部元素之间的大小关系我们不清楚, 但是该算法告诉我们可以通过不断选取新的基准将数组划分,可以使得这些「不可控的序列」逐渐变小直至消失,此时数组已经排好序,这就是快速排序要做的事情。

    (2) 堆排序原理

    其实就是利用了大顶堆的性质,而实质上它又同时是一颗完全二叉树。大顶堆的层级大小性质可以帮助我们控制部分数据的大小关系,完全二叉树的顺序储存性质可以帮助我们把数据按一定大小关系排列起来。大顶堆告诉我们上一层的数据比下一层的数据大,但我们并不清楚每一层内部元素之间的大小关系, 我们只能通过不断调整堆,让它自身不断生成大顶堆,这样会使每一层内部元素的大小产生调整,调整范围也会越来越小,直至排序完毕,这就是堆排序要做的事情。

    3 时间复杂度比较分析

    上面大多都是陈铺序述,熟悉算法的朋友可以跳过。下面我们聚焦于两个排序算法之间的迭代过程中的一些小细节分析:

    (1) 在快排的迭代过程中,我们所处理的 [比基准大的数],[比基准小的数] 序列中,在进行两个数之间大小比较时,在该局部范围内,产生「大于」或者「小于」的可能性是一样的。这意味着每比较一次必然会产生一次有意义的比较结果,会缩减接下来迭代的扫描工作量。

    (2) 我们再来看看堆排序。在每一次进行重新堆调整的时候,我们在迭代时其实就已经知道,上一层的结点值一定是比下面大的。为了打乱堆结构把最后一个元素与顶堆互换时,此时我们也已经知道,互换后的元素是一定比下一层的数要小的。而在迭代时为了调整堆我们还是要进行一次已经知道结果的比较,这无疑是没有什么价值的,也就是产生了一次没有意义的比较,对接下来的迭代工作量并没有任何进展。

    由上述不难看出,两种排序方式都是采用了分治的思想,注意到该两种算法在迭代实现时,大体上都分成了两条扫描路线:

    A. 快速排序:

    一是基于基准值调整大小时,对整个数组各项元素的扫描,该部分时间复杂度分N.

    二是不断产生新的基准值对数组进行划分所产生的迭代次数,该部分时间复杂度为log(n).

    (log(n)的由来:原数组不断二分会产生的序列为n, n/2, n/4, …, n/2^k, 其中k的值就是需要迭代的次数,而n/2^k最终会收敛于1,亦即n/2^k=1时, n=2^k, log转换: log(n) = k)

    B. 堆排序:

    一是在产生顶堆时对各个结点数之间的比较,会涉及到整个数组元素的扫描,该部分时间复杂度为n.

    二是在调整堆的时候,对非叶子节点的扫描,该部分时间复杂度为log(n);

    两者平均时间复杂度均为o(nlog(n))。

    对于快速排序 ,当数组的各项元素均相等,又或者是每一次迭代时选到的基准值恰恰是数组里的最值,此时的快排时间复杂度就为o(n^2). 因为此时每一次迭代划分数组所发生的比较都是无效比较。而这样的情况发生的概率为 1 / (n * (n/2) * (n/4) ...(n/2^k)), 这是非常小的概率事件了。

    而对于堆排序 ,碍于堆的特性,在迭代时所产生的无效比较概率是相对较大甚至为100%。 因此,在实际使用中,快速排序的使用常优于堆排序。

    本次作答如有错漏或不同见解,欢迎指出。