排序算法(1)插入排序的算法分析

导语

   今天,我们介绍的是排序算法经典的一种排序算法,这个算法是插入排序。

相信大家都玩过纸牌。插入排序的工作方式就像许多人排序一手扑克牌。

开始时,我们的左手为空并且桌子上的牌面朝下(意味着我们不在翻开之前并不知道下一张牌是多大的)。

然后,我们每次从那些牌中选出一张牌,并把它插入到正确的位置(一般我们认为左边的最小),我们从左到右(或从右到左)将它与已在手中的每张牌进行比较。
这里写图片描述

动态图演示如下:

这里写图片描述

算法分析

对于插入排序,我们将伪代码的过程命名为INSERTION-SORT
其中

  1. 参数是A[1..N],为长度n的一个需要排序的序列。
  2. A.length表示数组A中元素的数量

该算法在数组A中重排这些数,在任何时候,最多只有其中的常数个数字存储在数组外面。

等INSERTION-SORT结束时,输入数组A包含排序好的输出序列。

算法伪代码

INSERTION-SORT(A1   for j=2 to A.length
2       key = A[j]
3       //Insert A[j] into the sorted sequence A[1..j-1]
4       i = j - 1
5       while i > 0 and A[i] > key
6           A[i+1] = A[i]
7           i = i - 1
8       A[i+1]=key

图示分析

这里写图片描述

算法复杂度分析

INSERTION-SORT(A)代价次数
for j=2 to A.length c1 n
key = A[j] c2 n1
i = j - 1 c3 n1
while i > 0 and A[i] > key c4 nj=2tj
A[i+1] = A[i] c5 nj=2(tj1)
i = i - 1 c6 nj=2(tj1)
A[i+1]=key c7 n1

该算法的运行时间是执行每条语句的运行时间之和。基于此,我们可以计算在具有n个值输入上INSERTION-SORT(A)的运行时间T[n],我们将代价次数列对应元素之积求和,得

T(n)=c1n+c2(n1)+c3(n1)+c4j=2ntj+c5j=2n(tj1)+c6j=2n(tj1)+c7(n1)

最好情况下:

对于给定的n个需要排序的,若输入已排序,则出现最佳情况。这个时候,对于j=2,3,….,n,可以发现,当i取初值j-1时,有 A[i]key 。从而对j=2,3,…,n有 tj=1 ,也就是说只需要比较一次。

我估计说到这里,有些人看不懂,我就简单的说吧:

假设现在你左手中的牌都是已经排好序了的,而且是从小到大排序,现在你手上拿了一张牌,比你左手上的牌最右边(即是你手中牌中最大)还要大,那么你一定要保证牌是从小到大的排序,必然会把牌之间放在你牌的最右边。而这个过程,你只是和你本来有的牌的最大一张比较了一次。

所以最好的情况下的时间复杂度 Tn 为:

T(n)=c1n+c2(n1)+c3(n1)+c4(n1)+c7(n1)=(c1+c2+c3+c4+c7)n(c1+c2+c3+c4)

T(n)=an+b

其中 a b依赖于语句代价 ci

我们可以得出一个结论:

在最好情况下,插入排序的时间复杂度在 O(n) ,即 线 上完成排序。

最坏情况下:

若输入数组已方向排序,即按照递减排序排好了序,则导致最坏情况。我们必须把每个元素A[j]与整个已排序子数组A[1..j-1]中的每个元素都要进行比较,所以对j=2,3,…,n,有 tj=j

我估计有人问为什么 tj=j ,那么我就这样告诉你吧:

tj 是while语句进行比较语句的执行的次数,最后一次是进行i>0的判断,所以A[1..j-1]与A[j]实际上进行了j-1次比较,那么为什么进行j-1次比较呢,我们这么想,j代表我要加入第几张牌,我就以j=3来说,我即将加入第3张牌进入我左手的牌中(左手有两张牌,已经升序排列了好了),而这个牌比前面2个都要小,那么我是需要和比较两次才知道的,所以一共比较j-1次。

值得注意的是,这时候的

j=2nj=n(n+1)21

以及
j=2n(j1)=n(n1)2

上述是求和递推公式,我并不会给予证明,毕竟这可不是数学教学。

所以最坏的情况下的时间复杂度 Tn 为:

T(n)=c1n+c2(n1)+c3(n1)+c4(n(n+1)21)+c5(n(n1)2)+c6(n(n1)2)+c7(n1)=(c42+c52+c62)n2+(c1+c2+c3+c42c52c62+c7)n(c2+c3+c4+c7)


T(n)=an2+bn+c

其中 a b c 依赖于语句代价ci

我们可以得出一个结论:

在最坏情况下,插入排序的时间复杂度在 O(n2) ,即 n 上完成排序。

平均情况和最坏情况差不多,复杂度也在 O(n2)

结语

接下来,我将会在下一文中编写出语言版本去实现算法。敬请期待。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuYunTan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值