当前位置:   article > 正文

【C语言】【数据结构初阶】 插入排序 ,希尔排序 - 详解_将数列进行插入排序

将数列进行插入排序

一.插入排序

1.插入排序介绍

插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。 按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序 。

2.代码

1.单趟排序(即插入一个数据)

以从小到大的排序为例。

  1. int end; //end为原来的有序的序列的最后一个数字的下标
  2. x = a[end + 1]; //x为需要插入的数据
  3. while (end >= 0)
  4. {
  5. //当x比序列的最后一个数字要小时,最后一个数字往后挪一个位置
  6. //当x比序列的倒数第二个数也小时,倒数第二个数字也往后挪一个位置
  7. //以此类推,直到x比某个数字大时,跳出循环
  8. if (a[end] > x)
  9. {
  10. a[end + 1] = a[end];
  11. end--;
  12. }
  13. else
  14. {
  15. break;
  16. }
  17. }
  18. //此时,如果x比原来的序列的所有数字都小,那么end为-1,end+1为0,即x会插入到a[0]的位置
  19. //否则,x会插入到比x小的数字的后面,比x大的数字的前面
  20. a[end + 1] = x;

这样我们就实现了将一个数字插入一个有序数列。

2.完整排序

那么,在实现了单趟排序的基础上,我们可以实现将一个无序的数组进行从大到小或者从小到大的排序。

我们还是以从小到大的排序为例。(要想实现从大到小,改变大于小于号即可)

  1. void InsertSort(int* a, int n)
  2. {
  3. assert(a); //断言
  4. int end = 0;
  5. int x = 0;
  6. for (end = 0; end <= n - 2; end++)
  7. {
  8. //当end为数组的倒数第二个元素时,x为数组的最后一个元素,所以end <= n - 2
  9. x = a[end + 1];
  10. while (end >= 0)
  11. {
  12. if (a[end] > x)
  13. {
  14. a[end + 1] = a[end];
  15. end--;
  16. }
  17. else
  18. {
  19. break;
  20. }
  21. }
  22. a[end + 1] = x;
  23. }
  24. }

3.运行结果

二.希尔排序 

1.概念

希尔排序(Shell Sort)属于插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

将一列数分为gap组,比如gap为3时,分组如下:

 将每一组内分别进行插入排序,gap为3时,即需要进行3次插入排序的过程。每一组插入排序结束后,其组内的数字就是升序。

比如:红箭头所指的一组:1  3  9;

蓝箭头所指的一组:2  5  6;

绿框的一组:4  7  8;

总的数列:1  2  4  3  5  7  9  6  8;

当gap组数据分别进行插入排序之后,该数列就变得更加相对有序了。

2.代码

  1. //希尔排序
  2. void ShellSort(int* a, int n)
  3. {
  4. int gap = n;
  5. while (gap > 1)
  6. {
  7. gap /= 2;
  8. //gap不断变小,直至为1
  9. int j = 0;
  10. //将gap组数据分别进行插入排序
  11. for (j = 0; j < gap; j++)
  12. {
  13. int end = 0;
  14. //一组数据的插入排序
  15. for (end = j; end < n - gap; end += gap)
  16. {
  17. int x = a[end + gap];
  18. while (end >= 0)
  19. {
  20. if (a[end] > x)
  21. {
  22. a[end + gap] = a[end];
  23. end -= gap;
  24. }
  25. else
  26. {
  27. break;
  28. }
  29. }
  30. a[end + gap] = x;
  31. }
  32. }
  33. }
  34. }

3.代码略作改动

实质是:2中的代码是将gap组一组一组排序,而下面的代码中,则是按照顺序一个一个排序。

  1. //希尔排序稍加改动(减少了循环嵌套,代码简化,但效率并未优化)
  2. void ShellSort2(int* a, int n)
  3. {
  4. int gap = n;
  5. while (gap>1)
  6. {
  7. gap /= 2;
  8. int i = 0;
  9. for (i = 0; i < n - gap; i++)
  10. {
  11. int end = i;
  12. int x = a[end + gap];
  13. while (end >= 0)
  14. {
  15. if (a[end] > x)
  16. {
  17. a[end + gap] = a[end];
  18. end -= gap;
  19. }
  20. else
  21. {
  22. break;
  23. }
  24. }
  25. a[end + gap] = x;
  26. }
  27. }
  28. }

4.运行结果

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/821428
推荐阅读
相关标签
  

闽ICP备14008679号