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

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


1. 插入排序


1.1 排序问题

输入:n个数的一个序列 A = <a1a_1 , a2a_2, …, ana_n>。

输出:输入序列的一个排序AA^\prime​ = < a1a_1^\prime​ , a2a_2\prime​, …, ana_n\prime​ >,满足 a1a_1^\prime​ \leq​ a2a_2\prime​ \leq​\leq​ ana_n\prime​

原理

  从整个待排序列中选出一个元素插入到已经有序的子序列中去,得到一个有序的、元素加一的子序列,直到整个序列的待插入元素为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行的每次执行时间为aia_i​

INSERTION-SORT(A) 代价 次数
for 2 to A.length c1c_1 n
  key = A[j]; c2c_2 n - 1
  // Insert A[j] into the sorted sequence A[1…j-1]  0 n - 1
  i = j - 1;  c4c_4 n - 1
  while i > 0 and A[j] > key  c5c_5 j=2n\sum_{j=2}^ntjt_j​
    A[i + 1] = A[i] c6c_6 j=2n\sum_{j=2}^n(tjt_j​ - 1)
     i = i - 1 c7c_7 j=2n\sum_{j=2}^n(tjt_j - 1)
  A[i + 1] = key c8c_8 n - 1

其中:

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

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

T(n) = c1c_1​n + c2c_2​(n - 1) + c4c_4​(n - 1) + c5c_5​j=2n\sum_{j=2}^n​tjt_j​ + c6c_6​ j=2n\sum_{j=2}^n​(tjt_j​ - 1) + c7c_7​j=2n\sum_{j=2}^n​(tjt_j​ - 1) + c8c_8​(n - 1)

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

T(n)=c1T(n) = c_1n + c2c_2(n - 1) + c4c_4(n - 1) + c5c_5(n - 1) + c8c_8(n - 1)

=c1+c2+c4+c5+c8nc2+c4+c5+c8= (c_1​+ c_2​ + c_4​ + c_5​ + c_8​)n - (c_2 + c_4 + c_5 + c_8​)

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

1.3.2 最坏情况

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

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

T(n) = c_1 n + c2c_2(n-1) + c4c_4(n-1) + c5c_5( n(n+1)21\frac{n(n+1)}{2}-1) + c6(n(n1)2)c_6(\frac{n(n-1)}{2}) + c7c_7(n(n1)2\frac{n(n-1)}{2}) + c8c_8(n-1)

= (c52+c62+c72)(\frac{c_5}{2} + \frac{c_6}{2} +\frac{c_7}{2} )n2n^2 + (c1+c2+c4+c52c62c72+c8)(c_1 + c_2 +c_4 + \frac{c_5}{2} -\frac{c_6}{2} \frac{c_7}{2} + c_8)nn-(c2+c4+c5+c8c_2+c_4+c_5+c_8)

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

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

  • 算法的最坏情况提供了一个上界,知道了上界能确保算法不需要更长的时间。
  • 对于某些算法最坏情况经常出现。
  • “平均情况”往往与最坏情况大致一样差。
发布了35 篇原创文章 · 获赞 4 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览