分类目录:《算法设计与分析》总目录
相关文章:
· 排序算法(一):插入排序
· 排序算法(二):归并排序
· 排序算法(三):堆排序
· 排序算法(四):选择排序
· 排序算法(五):冒泡排序
· 排序算法(六):希尔排序
· 排序算法(七):快速排序
· ①基础知识
· ②快速排序的性能
· ③快速排序的随机化
· ④快速排序的分析
· 排序算法(八):计数排序
· 排序算法(九):基数排序
· 排序算法(十):桶排序
· 排序算法:比较排序算法的下界
· 排序算法:十大排序算法总结
我们在《排序算法》系列的开头介绍了几种能在时间内排序
个数的算法。归并排序和堆排序达到了最坏情况下的上界;快速排序在平均情况下达到该上界。而且,对于这些算法中的每个,我们都能给出
个输入数值,使得该算法能在
时间内完成。
《排序算法》的1-7节的算法都有一个有趣的性质:在排序的最终结果中,各元素的次序依赖于它们之间的比较。我们把这类排序算法称为比较排序。
下文将证明对包含个元素的输入序列来说,任何比较排序在最坏情况下都要经过
次比较。因此,归并排序和堆排序是渐近最优的,并且任何已知的比较排序最多就是在常数因子上优于它们。
从《排序算法》的第8节开始,我们讨论了三种线性时间复杂度的排序算法:计数排序、基数排序和桶排序。当然,这些算法是用运算而不是比较来确定排序顺序的。因此,下界对它们是不适用的。
在一个比较排序算法中,我们只使用元素间的比较来获得输入序列的元素间次序的信息。也就是说,给定两个元素
和
,可以执行
、
、
、
、
中的一个比较操作来确定它们之间的相对次序。我们不能用其他方法观察元素的值或者它们之间的次序信息。
不失一般性,在本文中,我们不妨假设所有的输入元素都是互异的。给定了这个假设后的比较就没有意义了。因此,我们可以假设不需要这种比较。同时,注意到
、
、
和
都是等价的,因为通过它们所得到的关于
和
的相对次序的信息是相同的。这样,又可以进一步假设所有比较采用的都是
形式。
决策树模型
比较排序可以被抽象为一棵决策树。决策树是一棵完全二叉树,它可以表示在给定输入规模情况下,某一特定排序算法对所有元素的比较操作。其中,控制、数据移动等其他操作都被忽略了。下图显示了《排序算法(一):插入排序》中插入排序算法作用于包含三个元素的输入序列的决策树情况。
在决策树中,每个内部结点都以标记,其中,
和
满足
和
,
是输入序列中的元素个数。每个叶结点上都标注一个序列
。排序算法的执行对应于一条从树的根结点到叶结点的路径。每一个内部结点表示一次比较
,左子树表示一旦我们确定
之后的后续比较,右子树则表示在确定了
后的后续比较。当到达一个叶结点时,表示排序算法已经确定了一个顺序
。因为任何正确的排序算法都能够生成输入的每一个排列,所以对一个正确的比较排序算法来说,
个元素的
种可能的排列都应该出现在决策树的叶结点上。而且,每一个叶结点都必须是可以从根结点经由某条路径到达的,该路径对应于比较排序的一次实际执行过程。因此,在后续内容中,我们将只考虑每一种排列都是一个可达的叶结点的决策树。
最坏情况的下界
在决策树中,从根结点到任意一个可达叶结点之间最长简单路径的长度,表示的是对应的排序算法中最坏情况下的比较次数。因此,一个比较排序算法中的最坏情况比较次数就等于其决策树的高度。同时,当决策树中每种排列都是以可达的叶结点的形式出现时,该决策树高度的下界也就是比较排序算法运行时间的下界。所以我们可得:在最坏情况下,任何比较排序算法都需要做次比较。而本系列介绍的堆排序(《排序算法(三):堆排序》)和归并排序(《排序算法(二):归并排序》)都是渐近最优的比较排序算法。