分析归并排序的时间复杂度,并证明
归并排序(Merge sort)
归并排序采用了分而治之的思想,过程可概括为以下几步:
- 将给定的待排序的数组一分为二
- 对两部分数组分别使用归并排序使其有序
- 将有序的两部分数组合并
MergeSort(arr[],l,r)
if r > l
middle m = (l+r)/2
mergeSort(arr,l,m)
mergeSort(arr,m+1,r)
merge(arr,l,m,r)
复杂度证明(展开法)
根据算法的第一步可知
T(N)=2T(2N)+O(N)
- T(n) 表示对n个数进行归并排序
- 2T(n/2)表示将 n 个数分成两部分分别进行归并排序
- O(n) 表示对两个子过程结束之后合并的过程
T(N)=2T(N/2)+O(N)=2(2T(N/4)+O(2N))+O(N)=4T(N/4)+O(N)+2O(2N)=4T(N/4)+2O(N)=8T(N/8)+3O(N)⋮=2kT(N/2k)+kO(N)
当 N=2K 时迭代停止,此时 K=log2N
代入,得
T(N)=NT(1)+log2N⋅O(N)=O(NlogN)
PS1: 这里假设 N 为偶数,如果不是,那么假设 N 介于 2i 和 2i+1 之间,通过估计 T(2i+1) 来确定 T(N) 的上界
PS2: O(N)=aN=2O(2N),因为大O复杂度只看上界,所以其常数项可以被忽略, 来自于把一个待排序序列分解成两个序列的时间,这一操作可以在常数项内完成(设定一个下标的时间)。
复杂度证明(假设法)
假设 T(N)=O(NlogN)≤aNlogN+b,a,b 为常数。
N=1 时,T(1)=b,成立
N=k+1 时,2N=2k+1≤k 在 N≥2 时成立
T(2N)≤a(2N)log2N+b
因此,
T(N)≤2T(2N)+C2N//代入≤2(a(2Nlog2N+b)+C2N=aNlogN−aNlog2+C2N+2b=aNlogN−aN+C2N+2b
即
T(N)≤aNlogN−aN+C2N+2b
又因为假设 T(N)=O(NlogN)≤aNlogN+b,使假设成立,则
T(N)≤aNlogN−aN+C2N+2b≤aNlogN+b
解红线的式子,得
−aN+C2N+b≤0
当 a=C1+C2,b=C1 时不等式成立。
得证