当前位置: 首页 > news >正文

数据结构——希尔排序

希尔排序

直接插入排序和折半插入排序在数组基本有序时效率很高,但面对无序数组时,时间复杂度为O(n2)O(n^2)O(n2)。希尔排序通过“分组插入、逐步缩增量”的策略,大幅提升了插入排序的效率,它是插入排序的进阶优化版本。

1. 希尔排序的核心思想

希尔排序将待排序数组按“增量(间隔)”分成若干组,每组内的元素进行直接插入排序;然后逐步缩小增量,重复分组和组内排序的过程,直到增量为1时,进行最后一次全局的直接插入排序。这里的“增量”决定了分组的依据,例如增量为ddd时,下标为i,i+d,i+2d,…i, i+d, i+2d, \dotsi,i+d,i+2d,的元素为一组。

通过这种“先宏观调整,再微观整理”的方式,数组会逐渐趋于有序,最终在增量为1时,插入排序的效率会非常高(因为数组已基本有序)。

2. 希尔排序的执行流程(结合示例图片)

我们以示例图片中的初始关键字arr = {49, 38, 65, 97, 76, 13, 27, 49, 55, 04}为例,详细分析希尔排序的每一趟过程:

  • 第一趟:增量d1=5d_1 = 5d1=5
    按增量5分组,数组被分为5组:(49,13)(38,27)(65,49)(97,55)(76,04)。对每组内的元素进行直接插入排序:

    • (49,13)排序后为(13,49)
    • (38,27)排序后为(27,38)
    • (65,49)排序后为(49,65)
    • (97,55)排序后为(55,97)
    • (76,04)排序后为(04,76)
      将各组结果按顺序拼接,得到第一趟排序结果:13, 27, 49, 55, 04, 49, 38, 65, 97, 76(如图中“第一趟排序结果”所示)。
  • 第二趟:增量d2=3d_2 = 3d2=3
    缩小增量为3,重新分组:(13,55,38,76)(27,04,65)(49,49,97)。对每组内的元素进行直接插入排序:

    • (13,55,38,76)排序后为(13,38,55,76)
    • (27,04,65)排序后为(04,27,65)
    • (49,49,97)排序后为(49,49,97)
      拼接后得到第二趟排序结果:13, 04, 49, 38, 27, 49, 55, 65, 97, 76(如图中“第二趟排序结果”所示)。
  • 第三趟:增量d3=1d_3 = 1d3=1
    增量缩小为1,此时数组已基本有序,进行一次全局的直接插入排序。最终得到有序数组:04, 13, 27, 38, 49, 49, 55, 65, 76, 97(如图中“第三趟排序结果”所示)。

3. 希尔排序的代码实现

希尔排序的关键是选择增量序列,常见的增量选择是“初始增量为n/2n/2n/2,每次减半”(nnn为数组长度)。以下是希尔排序的C语言实现:

void ShellSort(int arr[], int n) {int d, i, j, temp;for (d = n / 2; d > 0; d /= 2) { // 增量逐步缩小for (i = d; i < n; i++) {   // 遍历每组的第二个及以后元素temp = arr[i];for (j = i - d; j >= 0 && arr[j] > temp; j -= d) {arr[j + d] = arr[j]; // 组内元素后移}arr[j + d] = temp;      // 插入元素}}
}

代码说明:

  • 外层循环控制增量ddd的缩小,从n/2n/2n/2开始,每次减半;
  • 中层循环遍历“每组”的待插入元素(从第ddd个元素开始,因为每组第一个元素默认在组内有序);
  • 内层循环在组内进行直接插入排序,通过j -= d实现组内元素的比较和移动。
4. 希尔排序的性能与特性
  • 时间复杂度:希尔排序的时间复杂度与增量序列的选择密切相关,目前没有精确的数学分析,但在平均情况下,其时间复杂度为O(n1.3)O(n^{1.3})O(n1.3),远优于直接插入排序的O(n2)O(n^2)O(n2)
  • 空间复杂度:仅需一个临时变量temp,空间复杂度为O(1)O(1)O(1)
  • 稳定性:由于分组排序时会打乱相同元素的相对顺序,因此希尔排序是不稳定的
5. 适用场景

希尔排序适合数据量较大且无序的场景,它能快速将数组“宏观调整”为基本有序,大幅降低最终插入排序的时间开销。例如,在处理 thousands 级别的数据时,希尔排序的效率明显高于直接插入排序。

综上,希尔排序通过“分组插入、逐步缩增量”的策略,解决了直接插入排序在无序数组上的低效问题,是插入排序家族中性能更优的算法。理解其分组排序的逻辑和增量选择的影响,能帮助我们在实际场景中选择更高效的排序方式。

http://www.dtcms.com/a/524093.html

相关文章:

  • 分组卷积(Grouped Convolution)原理与应用详解
  • 【信道利用率】为什么卫星链路用 SW 协议效率低?ARQ 信道利用率公式 + 计算题全解!
  • 三极管MOS管
  • PHP拆分重组pdf,php拆分pdf指定页数,并合并成新pdf
  • 详解C语言数组
  • 鹤山做网站公司建设网站宣传
  • 微信网站开发视频教程开发一个小软件多少钱
  • 释放内存与加速推理:PyTorch的torch.no_grad()与torch.inference_mode()
  • 论文笔记(九十六)VGGT: Visual Geometry Grounded Transformer
  • 城市基础设施安全运行监管平台
  • 网络 UDP 和 TCP / IP详细介绍
  • 数据结构(8)
  • [cpprestsdk] ~异步流处理(eg`basic_istream`、`basic_ostream`、`streambuf`) 底层
  • Linux 查找符合条件的文档
  • ​九小场所 / 乡镇监督防火 ——1 个平台管水源 / 隐患,整改率提 80%
  • 郑州做网站找绝唯科技地方类门户网站
  • 哪里可以做免费的物流网站国外室内设计案例网站
  • 【Linux系统】从零掌握make与Makefile:高效自动化构建项目的工具
  • ML:Supervised/Unsupervised
  • 开发网站多少钱北京 工业网站建设公司排名
  • 【后端开发面试题】
  • 【coze】基础概念与使用
  • Java 语法糖详解(含底层原理)
  • 企业网站介绍越南做企业网站
  • 免费建设电影网站宁波优化推广找哪家
  • JAVA1024 类 object类 包装类 享元模式 ;类继承 :interface ;构造方法
  • 树与二叉树的奥秘全解析
  • 《Python 正则表达式完全指南:从入门到精通》(AI版)
  • 【linux】vim快速清空整个文件
  • 基于单片机的故障检测自动保护智能防夹自动门设计及LCD状态显示系统