数据结构与算法(一)插入排序

数据结构与算法(一)插入排序


1. 插入排序


1.1 排序问题

输入:n个数的一个序列 A = < a 1 a_1 a1 , a 2 a_2 a2, …, a n a_n an>。

输出:输入序列的一个排序 A ′ ​ A^\prime​ A = < a 1 ′ ​ a_1^\prime​ a1 , a 2 ′ ​ a_2\prime​ a2, …, a n ′ ​ a_n\prime​ an >,满足 a 1 ′ ​ a_1^\prime​ a1 ≤ ​ \leq​ a 2 ′ ​ a_2\prime​ a2 ≤ ​ \leq​ ≤ ​ \leq​ a n ′ ​ a_n\prime​ an

原理

  从整个待排序列中选出一个元素插入到已经有序的子序列中去,得到一个有序的、元素加一的子序列,直到整个序列的待插入元素为0,则整个序列全部有序。

在实际的算法中,我们经常选择序列的第一个元素作为有序序列(因为一个元素肯定是有序的),我们逐渐将后面的元素插入到前面的有序序列中,直到整个序列有序。

1.2 实现伪代码

INSERTION-SORT(A)
for 2 to A.length
    key = A[j];
    // Insert A[j] into the sorted sequence A[1..j-1]
    i = j - 1;
    while i > 0 and A[j] > key
        A[i + 1] = A[i]
        i = i - 1
    A[i + 1] = key

1.3 步骤解析

举例:对数组A = <5, 2, 4, 6,1, 3>进行插入排序(升序)

在这里插入图片描述

1.3 算法分析

假设第i行的每次执行时间为 a i ​ a_i​ ai

INSERTION-SORT(A)代价次数
for 2 to A.length c 1 c_1 c1n
  key = A[j]; c 2 c_2 c2n - 1
  // Insert A[j] into the sorted sequence A[1…j-1] 0n - 1
  i = j - 1;  c 4 c_4 c4n - 1
  while i > 0 and A[j] > key  c 5 c_5 c5 ∑ j = 2 n \sum_{j=2}^n j=2n t j ​ t_j​ tj
    A[i + 1] = A[i] c 6 c_6 c6 ∑ j = 2 n \sum_{j=2}^n j=2n( t j ​ t_j​ tj - 1)
     i = i - 1 c 7 c_7 c7 ∑ j = 2 n \sum_{j=2}^n j=2n( t j t_j tj - 1)
  A[i + 1] = key c 8 c_8 c8n - 1

其中:

  • t j t_j tj表示对那个值j第5行执行while循环的次数
  • 当一个forwhile循环按通常的方式(即由于循环头中的测试)退出时,执行测试的次数比执行循环体的次数多1
  • 注释是不可执行的语句,所以不需要时间

由上表的次数代价相乘我们可以得到运行时间T[n]:

T(n) = c 1 ​ c_1​ c1n + c 2 ​ c_2​ c2(n - 1) + c 4 ​ c_4​ c4(n - 1) + c 5 ​ c_5​ c5 ∑ j = 2 n ​ \sum_{j=2}^n​ j=2n t j ​ t_j​ tj + c 6 ​ c_6​ c6 ∑ j = 2 n ​ \sum_{j=2}^n​ j=2n( t j ​ t_j​ tj - 1) + c 7 ​ c_7​ c7 ∑ j = 2 n ​ \sum_{j=2}^n​ j=2n( t j ​ t_j​ tj - 1) + c 8 ​ c_8​ c8(n - 1)

1.3.1 最佳情况
我们都知道,当输入数组已经排好序时是插入排序最佳情况。即在伪代码的第5行,i 取初值 j - 1时, 有A[j] ≤ \leq key。从而对于j = 2, 3, … ,n,有 t j t_j tj = 1。故最佳情况的运行时间为:

T ( n ) = c 1 T(n) = c_1 T(n)=c1n + c 2 c_2 c2(n - 1) + c 4 c_4 c4(n - 1) + c 5 c_5 c5(n - 1) + c 8 c_8 c8(n - 1)

= ( c 1 ​ + c 2 ​ + c 4 ​ + c 5 ​ + c 8 ​ ) n − ( c 2 + c 4 + c 5 + c 8 ​ ) = (c_1​+ c_2​ + c_4​ + c_5​ + c_8​)n - (c_2 + c_4 + c_5 + c_8​) =c1+c2+c4+c5+c8nc2+c4+c5+c8

= Θ ( n ) ​ = \Theta(n)​ =Θ(n)

1.3.2 最坏情况

最坏情况则是,每个元素A[j]都要和整个已排序子数组A[1…j - 1] 中的每个元素进行比较,所以 j = 2, 3, …, n,有 t j = j ​ t_j = j​ tj=j .

则有: ∑ j = 2 n j = n ( n + 1 ) 2 − 1 ​ \sum_{j=2}^n j = \frac{n(n+1)}{2}-1​ j=2nj=2n(n+1)1 ∑ j = 2 n ( j − 1 ) = n ( n − 1 ) 2 ​ \sum_{j=2}^{n}(j-1) = \frac{n(n-1)}{2}​ j=2n(j1)=2n(n1)

T(n) = c_1 n + c 2 c_2 c2(n-1) + c 4 c_4 c4(n-1) + c 5 c_5 c5( n ( n + 1 ) 2 − 1 \frac{n(n+1)}{2}-1 2n(n+1)1) + c 6 ( n ( n − 1 ) 2 ) c_6(\frac{n(n-1)}{2}) c6(2n(n1)) + c 7 c_7 c7( n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)) + c 8 c_8 c8(n-1)

= ( c 5 2 + c 6 2 + c 7 2 ) (\frac{c_5}{2} + \frac{c_6}{2} +\frac{c_7}{2} ) (2c5+2c6+2c7) n 2 n^2 n2 + ( c 1 + c 2 + c 4 + c 5 2 − c 6 2 c 7 2 + c 8 ) (c_1 + c_2 +c_4 + \frac{c_5}{2} -\frac{c_6}{2} \frac{c_7}{2} + c_8) (c1+c2+c4+2c52c62c7+c8) n − n- n( c 2 + c 4 + c 5 + c 8 c_2+c_4+c_5+c_8 c2+c4+c5+c8)

= Θ ( n 2 ) \Theta(n^2) Θ(n2)

1.3.3两种情况的区别
相比于最佳情况,对于我们分析算法优劣最有用的应该是最坏情况,因为:

  • 算法的最坏情况提供了一个上界,知道了上界能确保算法不需要更长的时间。
  • 对于某些算法最坏情况经常出现。
  • “平均情况”往往与最坏情况大致一样差。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值