欢迎光临散文网 会员登陆 & 注册

C语言实现插入排序

2023-04-17 16:41 作者:风勉八八  | 我要投稿

问题描述:

    排序问题:

    输入:N个数的一个序列<a1,a2,a3,...,an>。

    输出:输入序列的一个序列<a1',a2',a3',...,an'>,满足a1'<=a2'<=a3'<=...<=an'。

虽然排序的是一个序列,但实际上来说,输入的是有N个元素的数组。所以每一个被排序的数在排序过程中被称为关键字key。

插入排序的过程:

遍历数组中的每个关键字key,将它的位置空出来,然后从key开始往前遍历,直到找到找排在他前面的比它小的value,key之前value之后的这一段序列后移,然后将key插入到value后面,这就完成了一次插入。

具体实现:

时间复杂度分析:

行号         算法语句                       执行次数          代价 c_i

1          int i,j,key;                              1                           c_1

2          for (j=1;j<=length;j++)            n+1                      c_2

3          key=array[j];                           n                         c_3

4          i=j-1;                                       n                          c_4

5          while(i>=0&&array[i]>key)          %5Csum_%7Bj%3D2%7D%5E%7Bn%7Dt_j                            c_5

6          array[i+1]=array[i];                       %5Csum_%7Bj%3D2%7D%5E%7Bn%7D(t_j-1)                  c_6

7          i=i-1;                                             %5Csum_%7Bj%3D2%7D%5E%7Bn%7D(t_j-1)                  c_7

8          array[i+1]=key;                               n                                  c_8

9          return array;                                     1                                 %20c_9


则其时间复杂度为:

T(n)%20%3D%20c_1%20%2B%20c_2(n%2B1)%20%2B%20c_3n%20%2B%20c_4n%20%2B%20c_5%5Csum_%7Bj%3D2%7D%5Ent_j%20%2B%20c_6%5Csum_%7Bj%3D2%7D%5Ent_j%20%2B%20c_7%5Csum_%7Bj%3D2%7D%5Ent_j%20%2B%20c_8n%20%2B%20c_9

将上面的式子合并相同的项,得到:

T(n)%20%3D%20c_1%20%2B%20c_2n%20%2B%20c_3n%20%2B%20c_4n%20%2B%20(c_5%2Bc_6%2Bc_7)%5Csum_%7Bj%3D2%7D%5Ent_j%20%2B%20c_8n%20%2B%20c_9

可以看到,第 2 至第 4 项的系数以及第八项都是 n,因此可以将它们合并为 4cn 的形式,其中 c%3Dc_2%2Bc_3%2Bc_4%2Bc_8,即:

T(n)%20%3D%20(c_5%2Bc_6%2Bc_7)%5Csum_%7Bj%3D2%7D%5Ent_j%20%2B%204cn%20%2B%20c_9%20%2Bc_1%20

在插入排序算法的最坏情况下,数组的元素按照降序排列,即每个元素都要移动到它应该插入的位置,因此第 j 个元素需要移动 j-1 次,因此:

t_j%20%3D%20j-1%2C%20j%3D2%2C3%2C%5Cldots%2Cn

t_j 代入 %5Csum_%7Bj%3D2%7D%5En%20t_j,得到:

%5Csum_%7Bj%3D2%7D%5En%20t_j%20%3D%20%5Csum_%7Bj%3D2%7D%5En%20(j-1)%20%3D%20%5Cfrac%7B(n-1)n%7D%7B2%7D

因此,在最坏情况下,(c_5%2Bc_6%2Bc_7)%5Csum_%7Bj%3D2%7D%5Ent_j可以转化为 (c_5%2Bc_6%2Bc_7)%5Cfrac%7B(n-1)n%7D%7B2%7D。将其代入原式,得到:

T(n)%20%3D%20(c_5%2Bc_6%2Bc_7)%5Cfrac%7B(n-1)n%7D%7B2%7D%20%2B%204cn%20%2B%20c_9%20%2Bc_1%20

因此,在最坏情况下,该插入排序算法的时间复杂度仍然是 O(n%5E2),其中 n 为数组长度。

输出非增序列:

要输出非增序列,需要对插入排序算法做一些修改。在原始算法中,每次将一个元素插入已排序序列中的适当位置,这样可以得到递增的序列。为了得到非增序列,需要修改插入操作的逻辑,即如果插入的元素小于或等于已排序序列中的某个元素,则将其插入到该元素的后面,否则插入到序列的最前面。

本文给出示例代码如下:

至此,插入排序完毕。


C语言实现插入排序的评论 (共 条)

分享到微博请遵守国家法律