ToB企服应用市场:ToB评测及商务社交产业平台

标题: 从插入排序到希尔排序 [打印本页]

作者: 徐锦洪    时间: 2025-2-19 23:56
标题: 从插入排序到希尔排序
从插入排序到希尔排序

  插入排序

  原理

  
插入排序是一种简朴直观的排序算法,其根本头脑是通过将每个元素逐个插入到已排序的部分中,渐渐构建一个有序序列。

  操作步骤

    
  
重复步骤:直到全部元素都处理完毕。

  排序过程

  
  
  代码实现

  1. /**
  2.  * @ 简单插入排序
  3.  * @ arr - 待排序的数组     num - 数组元素个数
  4.  * @ 要求从大到小排序数据
  5.  * */ 
  6. void simple_insertion_sort(int *arr, int num)
  7. {
  8.     int i, j, tmp;
  9.     for (i=1; i<num; i++) {
  10.         j = i - 1;      /* 有序部分最后一个索引 */
  11.         tmp = arr[i];   /* 当前待插入的元素 */
  12.         /* 1. 若插入数据比有序部分最后一个元素还小,无需处理 */
  13.         if (arr[j] >= tmp) {
  14.             continue;
  15.         }
  16.         /* 2. 查找带插入数据位置,并后移数据腾出位置 */
  17.         while (j >= 0) {          
  18.             if (arr[j] >= tmp)
  19.                 break;
  20.             arr[j+1] = arr[j];
  21.             j--;
  22.         }
  23.         /* 3. 插入到正确位置 */
  24.         arr[j+1] = tmp;
  25.     }
  26. }
复制代码
技能点

  
  进阶代码

  
插入排序,可以理解为从序列中第 1 个元素开始,隔断固定 1 个元素,进行的序列排序。

  
假设程序猿想要在序列中从任意元素 (start_pos) 位置开始,隔断固定元素个数 (gap) 提取成新的序列进行插入排序,此时代码又该怎样进行通用筹划呢?

  1. /**
  2.  * @ 插入排序
  3.  * @ arr - 待排序的数组                 num - 数组元素个数
  4.  * @ start_pos - 待处理元素起始位置     gap - 间隔
  5.  * @ 要求从大到小排序数据
  6.  * */ 
  7. void insertion_sort(int *arr, int num, int start_pos, int gap)
  8. {
  9.     int i;
  10.     int index;          /* 用于有序部分数据遍历索引 */
  11.     int insert_data;    /* 用于记录待插入的数据 */
  12.     for (i=start_pos+gap; i<num; i+=gap) {
  13.         index = i - gap;        /* 有序部分最后一个索引,从最后一个开始索引 */
  14.         insert_data = arr[i];   /* 当前待插入的元素 */
  15.         /* 1. 若插入数据比有序部分最后一个元素还小,无需处理 */
  16.         if (arr[index] >= insert_data) {
  17.             continue;
  18.         }
  19.         /* 2. 查找带插入数据位置,并后移数据腾出位置 */
  20.         while (index >= 0) {          
  21.             if (arr[index] >= insert_data)
  22.                 break;
  23.             arr[index + gap] = arr[index];
  24.             index -= gap;
  25.         }
  26.         /* 3. 插入到正确位置 */
  27.         arr[index + gap] = insert_data;
  28.     }
  29. }
复制代码

  运行效果

  
  
  总结

  
插入排序作为基础排序算法之一,虽然在最坏环境下性能不佳,但在某些特定场景下仍然具有其独特的优势。通过优化如“提前制止内层循环”等方法,可以在一定程度上提升效率,使其更恰当于小规模数据或部分有序的数据。然而,对于大规模数据来说,仍然建议使用更高效的排序算法。

  希尔排序

  原理

  
希尔排序是一种改进的插入排序,它答应在远距离的元素之间进行比较和互换,从而减少排序的时间复杂度。

    操作步骤

    排序过程

  
     
   
  代码实现

  1. /**
  2.  * @ 希尔排序,插入排序的优化
  3.  * @ arr - 待排序的数组     num - 数组元素个数
  4.  * @ 要求从大到小排序数据
  5.  * */ 
  6. void shell_sort(int *arr, int num)
  7. {
  8.     int i;
  9.     int gap = num / 2;    /* 控制间距, 默认从 num/2 开始 */
  10.     while (gap > 0) {           /* 控制间距 */
  11.         for (i=0; i<gap; i++) { /* 控制组数 */
  12.             /* 调用插入排序 */
  13.             insertion_sort(arr, num, i, gap);
  14.         }
  15.         gap /= 2;
  16.     }
  17. }
复制代码
分析

  
  运行效果

  
  缺点

  
  优化方法

  
  完备代码

  1. /**
  2.  * @Filename : insertion_sort.c
  3.  * @Revision : $Revision: 1.00 $
  4.  * @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
  5.  * @Description : 从插入排序一步一步到希尔排序
  6. **/
  7. #include <stdio.h>
  8. #include <string.h>
  9. #define MAX_NUM     8  
  10. staticint cnt = 0; /* 统计排序次数 */
  11. /**
  12.  * @ 打印数组
  13.  * @ arr - 待打印的数组     num - 数组元素个数
  14.  * */
  15. void print_arr(int *arr, int num) 
  16. {
  17.     int i;
  18.     for (i=0; i<num; i++)
  19.         printf("%02d ", arr[i]);
  20.     printf("\n");
  21. }
  22. /**
  23.  * @ 插入排序
  24.  * @ arr - 待排序的数组                 num - 数组元素个数
  25.  * @ start_pos - 待处理元素起始位置     gap - 间隔
  26.  * @ 要求从大到小排序数据
  27.  * */
  28. void insertion_sort(int *arr, int num, int start_pos, int gap)
  29. {
  30.     int i;
  31.     int index;          /* 用于有序部分数据遍历索引 */
  32.     int insert_data;    /* 用于记录待插入的数据 */
  33.     for (i=start_pos+gap; i<num; i+=gap) {
  34.         index = i - gap;        /* 有序部分最后一个索引,从最后一个开始索引 */
  35.         insert_data = arr[i];   /* 当前待插入的元素 */
  36.         cnt++;
  37.         /* 1. 若插入数据比有序部分最后一个元素还小,无需处理 */
  38.         if (arr[index] >= insert_data) {
  39.             printf("无需移位 第%02d次排序: ", cnt);
  40.             print_arr(arr, num);
  41.             continue;
  42.         }
  43.         /* 2. 查找带插入数据位置,并后移数据腾出位置 */
  44.         while (index >= 0) {          
  45.             if (arr[index] >= insert_data)
  46.                 break;
  47.             arr[index + gap] = arr[index];
  48.             index -= gap;
  49.         }
  50.         /* 3. 插入到正确位置 */
  51.         arr[index + gap] = insert_data;
  52.         printf("需要移位 第%02d次排序: ", cnt);
  53.         print_arr(arr, num);
  54.     }
  55. }
  56. /**
  57.  * @ 简单插入排序
  58.  * @ arr - 待排序的数组     num - 数组元素个数
  59.  * @ 要求从大到小排序数据
  60.  * */
  61. void simple_insertion_sort(int *arr, int num)
  62. {
  63.     printf("排序前数组内容: ");
  64.     print_arr(arr, num);
  65.     cnt = 0;    /* 清空统计次数 */
  66.     insertion_sort(arr, num, 0, 1);
  67.     printf("排序后数组内容: ");
  68.     print_arr(arr, num);
  69. }
  70. /**
  71.  * @ 希尔排序,插入排序的优化
  72.  * @ arr - 待排序的数组     num - 数组元素个数
  73.  * @ 要求从大到小排序数据
  74.  * */
  75. void shell_sort(int *arr, int num)
  76. {
  77.     int i;
  78.     int gap = num / 2;    /* 控制间距, 默认从 num/2 开始 */
  79.     printf("排序前数组内容: ");
  80.     print_arr(arr, num);
  81.     cnt = 0;    /* 清空统计次数 */
  82.     while (gap > 0) {           /* 控制间距 */
  83.         for (i=0; i<gap; i++) { /* 控制组数 */
  84.             /* 调用插入排序 */
  85.             insertion_sort(arr, num, i, gap);
  86.         }
  87.         gap /= 2;
  88.     }
  89.     printf("排序后数组内容: ");
  90.     print_arr(arr, num);
  91. }
  92. int main(void)
  93. {
  94.     int buf1[] = {3, 8, 5, 1, 2, 6, 9, 7};
  95.     int buf2[] = {3, 8, 5, 1, 2, 6, 9, 7};
  96.     printf ("----------简单插入排序---------\n");
  97.     simple_insertion_sort(buf1, MAX_NUM);
  98.     printf ("---------希尔排序---------\n");
  99.     shell_sort(buf2, MAX_NUM);
  100.     
  101.     return0;
  102. }
复制代码
运行效果

  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4