排序最快可以有多快?这取决于具体的模型,具体来说就是排序过程中被允许的操作。目前我们已经知道的排序有插入排序(Θ(n 2)),归并排序(Θ(nlogn)),快速排序(Θ(nlogn)),堆排序(Θ(nlogn)),他们的复杂度都不低于Θ(nlogn),那么有没有一种排序复杂度可以低于Θ(n)呢?
上面的四种算法都有一个共同点,它们一次只能比较两个数。在这种比较排序这种模型中,我们只能做比较操作来决定元素的相对顺序。比较排序的算法的运行速度永远不会快于nlogn。而不用比较排序时算法速度可以快于nlogn,甚至可以达到n。
决策树与比较排序
假设要对三个数进行排序,<a1, a2, a3>,决策树如下图:
树上的每一个节点表示一次比较操作,比较a1和a2,如果a1≤a2,走左子树,否则走右子树,当到达叶节点,就得到了一个答案。例如:a1=9, a2=4, a3=6,排序过程如上图红色路线所示。
决策树成长得很快,每一个非叶节点都会有一个下标i:j,i和j在1~n之间,表示要比较ai和aj的大小,并且每个非叶节点都有两个子树,左子树表示ai≤aj的情况下算法要做什么,后续要进行哪些比较,右子树表示ai>aj的情况。每个叶节点代表了一个排序结果。决策树就是把比较的所有可能结果列出来。
比较排序算法中,如果挑出一条特定的算法执行路径,它就对应决策树中一条从根节点到叶节点的路径。算法执行路径的运行时间,或者比较的次数就是对应决策树的深度。因此对于n个元素的输入,最坏的运行时间就是最长路径,也就是决策树的高度。
我们现在要证明所有的比较排序算法对应的决策树的高度至少是nlogn。
首先,叶节点的数目是n!。
其次,假设树的高度为h,那么叶子节点最多有2h个。
也就是说,2h≥n!,那么h≥log2n!,
由斯特林公式, n ! ≈ 2 π n   ( n e ) n n!\approx \sqrt{2\pi n}\, \left(\frac{n}{e}\right)^{n} n!≈2πn