当前位置:   article > 正文

算法 - C语言实现插入排序(Insert_sort)_插入排序c

插入排序c

在写插入排序的代码之前,我们先对插入排序的排序原理进行梳理:

插入排序一共分为三种,分别是:直接插入排序、分别插入排序、希尔排序

在严蔚敏的《数据结构(C语言版)》中对直接插入排序是这样定义的:

直接插入排序(Selection Insertion Sort)是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的记录新增1的有序表。

如下图,我在这里给出了一组数据:

int ar[] = {1,2,3,7,6,5,4};

我们在画板对这组数据利用插入排序法进行排序,并将每一趟的排序结果都写出来:

在这里我画出了上面给出的数组以及元素的下标。当i和j分别指向3号下标和4号下标时满足代码(if(ar[i] < ar[i - 1])),这时i下标指向的6 小于i - 1指向的 7 使函数继续往下执行,这时将7付给临时变量temp;

现在开启第二层for循环,此时原本的i - 1下标相当于第二层for循环里面的j下标,这时从j下标的位置从后向前扫描,只要前面的序列里面还有比j下标指向的元素更小的元素,就把前面的序列的每一个元素全部向后移动一个位置,这句话对应代码语句中的(ar[j + 1] = ar[j]),并且因为3<6<7,我们应该把6插入到3和7的中间位置,并且应该把三号下标对应的7元素向后移动一个位置。

我们这时开始执行插入存放ar[i]的temp,此时对应代码语句中的(ar[j + 1] = temp;)到这时我们再回到图中:

这就是插入排序的第五趟操作(因为前四次都是满足后面大于前面的规则的)。

此时,我们在执行第六趟操作时依旧依照上面的思路进行执行,当我们的i下标指向5号下标对应的5元素时,发现并不满足前面小于后面元素的规则,这时开始执行第二层for循环,将5和前面已经排序好的1,2,3,6,7这五个元素进行比较,最后发现 6>5>3 ,所以这时,我们将5赋值给temp临时值,将6和7元素统一向后迁移一位,再将存放5元素的temp赋值给此时3号下标对应的地方(这就是插入操作),至此,第六趟排序结束,继续执行第三趟排序也是此过程,直到排序全部完成:

插入排序的排序原理基本清晰,我们将思路代码化:

  1. void Insert_sort(int *ar,int len)//插入排序默认步长为1,使用于小量级序列
  2. {
  3. int temp = 0;
  4. int i = 0,j = 0;
  5. for(i = 1;i < len;i++){//第一个循环,插入排序是从第二个元素开始排序的,所以此处的i = 1
  6. if(ar[i] < ar[i - 1]){//限定条件:后面的元素小于前面的元素
  7. temp = ar[i];//利用临时变量保存后面的元素
  8. for(j = i - 1;j >= 0 && ar[j] > temp;j--){//这层循环是为了检查前面已经排序好的元素,循环执行的条件就是j下标不会低于0下标且前面已经排序好的元素出现了比临时变量更大的元素。
  9. ar[j + 1] = ar[j];//将前面已经排序好的元素统一向后迁移一位
  10. }
  11. ar[j + 1] = temp;//将temp中存放的值赋值给需要插入的位置上
  12. }
  13. }
  14. }

在这里我设置数组中的十个元素是计算机随机生成的小于20的数,我在第一个for循环后面添加了一个句子,要求函数每进行一次排序就进行一次序列的输出,我们看一下计算机进行的每趟排序与我们分析的是不是一样的:

如图,计算机生成的原始数据为:

{7,8,16,8,15,18,3,19,8,12};

显然,序列前面的3个元素都是满足后面大于前面的规则的,直到第四个元素,8 < 16这时已不满足规则,向下执行for循环,我们是从第一个元素开始比较的,所以是遍历两次,且前两次遍历序列的顺序是一样的。

我们看运行结果,前两次的结果确实是一样的。

此时因为16>8>=8所以应该把8元素插入在8和16之间,如图第三趟是符合我们的推理的。

依此类推,插入排序最终的结果为:

{3,7,8,8,8,12,15,16,18,19};

分析完成。

接下来我们对系统随机分布的10个小于20的整数进行排序,看看结果正不正确:

  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<stdlib.h>
  4. #include<assert.h>
  5. #include<time.h>
  6. #define MAXSIZE 10
  7. void initar(int *ar,int len)
  8. {
  9. assert(ar != nullptr);
  10. for(int i = 0;i < len;i++){
  11. ar[i] = rand() % 20;
  12. }
  13. }
  14. void showar(int *ar,int len)
  15. {
  16. assert(ar != nullptr);
  17. for(int i = 0;i < len;i++){
  18. printf("%d ",ar[i]);
  19. }
  20. printf("\n--------------------------\n");
  21. }
  22. void Insert_sort(int *ar,int len)//插入排序默认步长为1,使用于小量级序列
  23. {
  24. assert(ar != nullptr && len >= 0);
  25. int temp = 0;
  26. int i = 0,j = 0;
  27. for(i = 1;i < len;i++){//第一个循环,插入排序是从第二个元素开始排序的,所以此处的i = 1
  28. if(ar[i] < ar[i - 1]){//限定条件:后面的元素小于前面的元素
  29. temp = ar[i];//利用临时变量保存后面的元素
  30. for(j = i - 1;j >= 0 && ar[j] > temp;j--){//这层循环是为了检查前面已经排序好的元素,循环执行的条件就是j下标不会低于0下标且前面已经排序好的元素出现了比临时变量更大的元素。
  31. ar[j + 1] = ar[j];//将前面已经排序好的元素统一向后迁移一位
  32. }
  33. ar[j + 1] = temp;//将temp中存放的值赋值给需要插入的位置上
  34. }
  35. }
  36. }
  37. int main()
  38. {
  39. srand((unsigned int)time(NULL));
  40. int ar[MAXSIZE];
  41. initar(ar,MAXSIZE);
  42. printf("原始数据为:\n");
  43. showar(ar,MAXSIZE);
  44. printf("\n\n经过插入排序后的数据为:\n");
  45. Insert_sort(ar,MAXSIZE);
  46. showar(ar,MAXSIZE);
  47. return 0;
  48. }

运行结果为:

如图,成功的将系统随机生成的10个小于20的整数进行了从小到大的排序。 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号