前言
我之前介绍过的四种排序算法:插入排序、冒泡排序、快速排序和归并排序都是基于键值比较的排序算法。
这四种算法可以大体分为两个阵营,前两个是一次比较后交换至多消除一对逆序关系,而后两个基于分治的策略,一次比较交换后可能消除多于一个逆序关系,因此后两种在平均时间复杂度上达到了变态的nlogn量级,这在实际问题中的提升是巨大的。
但是算法设计人员总是贪心不满足的,基于键值比较的算法还有没有继续提升下去的可能性呢?
这篇文章告诉你基于键值比较的排序算法已经走到了尽头!
一、排序判定树
任意三个数a,b,c进行排序,可能的结果有3!=6种。我们以冒泡排序为例,可以写出下面这样一个排序判定树。
- 叶子节点代表最终的排序结果,共有3!=6个。
- 不论采用何种排序算法,只要是基于比较操作完成的排序都可以得到一颗高度相同、具有6个叶子节点的判定树。
- 判定树为二叉树,非叶节点为比较操作,叶子节点为可能的排序结果。
- 判定树的高度反映最坏情况下的比较次数,根节点深度为0(注意这和二叉树并不相同,二叉树根节点深度为1)。
- 对n个元素进行排序,其判定树的叶子节点共有n!个。
建议对之前讲过的四种排序算法都尝试写一下其排序判定树,以熟悉排序判定树的书写方法。
二、基于“比较”操作排序算法的时间复杂度分析
我们基于排序判定树来对基于键值比较的排序算法做时间复杂度分析。
- 最坏情况时间复杂度下界
高度为h的二叉树最多有
个叶子节点,n个不同数据元素排序的判定树的高度至少为log(n!)。
2. 平均情况时间复杂度下界
比较排序的平均时间复杂度下界为nlogn。
经过对最坏情况和平均情况的时间复杂度分析,我们可以自信的认为,基于键值比较的排序算法在最坏情况下至少做O(nlogn)次比较。而归并排序经过我们的分析,其最坏情况和平均时间复杂度都是O(nlogn)。由此可以证明归并排序是最优的基于比较操作的排序。
那么提出这样一道证明题:
如何证明归并排序是最优的基于比较的排序?
我们分两步进行证明:
- 证明归并排序的最坏情况时间复杂度为
。
- 证明基于比较排序算法最坏情况时间复杂度为
。
- 所以,归并排序是一个最优的基于比较的排序算法。