原地归并排序算法的复杂度分析

几篇排位很高的和原地归并算法的博客比如:
https://blog.csdn.net/acdreamers/article/details/24244643
都将原地归并算法的复杂度归为 O ( n log ⁡ n ) O(n\log n) O(nlogn)的。

但实际上经过一番计算发现,利用线性数组+手摇算法实现的原地归并,算法复杂度在 O ( n 2 ) O(n^2) O(n2)
通过链表实现才是 O ( n log ⁡ n ) O(n\log n) O(nlogn)的。

链表实现nlogn

借用原文章中利用线性数组实现的图,简单说明这一点。
在这里插入图片描述

假设利用单向链表进行实现,我们将图中ijindex之前的元素用三个指针p1,p2,p3指向。利用如下过程实现常数时间的手摇。

tmp = p1->next;
p1->next = p2->next;
p2->next = p3->next;
p3->next = tmp;
delete tmp;

那么即便最坏的情况也只是进行n/2次链表手摇。
T ( n ) = c ⋅ n 2 + 2 T ( n 2 ) T(n)=c\cdot\frac{n}{2}+2T(\frac{n}{2}) T(n)=c2n+2T(2n)
复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

手摇数组实现n方

相比之前提到的利用线性数组+手摇实现的,我们可以构造这样一个序列:

1,3,5,7,   2,4,6,8

这样每推进一位就需要进行一次手摇。而每次手摇算法的开销为 n 2 ⋅ 1 2 \displaystyle\frac{n}{2}\cdot\frac{1}{2} 2n21,随序列剪短,需要进行手摇的序列长度从 n 2 \frac{n}{2} 2n逐一缩短为1。等差求和为 c n 2 cn^2 cn2
但注意,这个算法复杂度并非 n 2 log ⁡ n n^2\log n n2logn 其实就算n方也本来就不如用冒泡
T ( n ) = c n 2 + 2 T ( n 2 ) T(n)=cn^2+2T(\frac{n}{2}) T(n)=cn2+2T(2n)

求和为 ∑ k = 0 ∞ c ( n 2 k ) 2 ⋅ 2 k = c n 2 ∑ k = 0 ∞ 1 2 k \sum\limits_{k=0}^\infty c\left(\frac{n}{2^k}\right)^2\cdot 2^{k}=cn^2\sum\limits_{k=0}^\infty \frac{1}{2^k} k=0c(2kn)22k=cn2k=02k1
等号右边级数显然收敛到一个常数,故为 O ( n 2 ) O(n^2) O(n2)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值