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

希尔排序:高效插入排序的进阶之道

希尔排序:高效插入排序的进阶之道

  • 基本概念
  • 工作原理
  • 增量序列的选择
  • 实现
  • 分析

基本概念

希尔排序(Shell Sort)是插入排序的改进版本,由计算机科学家唐纳德・希尔(Donald Shell)于 1959 年提出。它通过引入「增量序列」的概念,打破了插入排序 “只能相邻元素交换” 的限制,大幅提升排序效率,尤其适合中等规模的数组排序。

与普通插入排序(仅能交换相邻元素)不同,希尔排序先通过 较大的间隔(增量) 对元素 “分组排序”,逐步缩小间隔,最终在间隔为 1 时退化为普通插入排序(此时数组已接近有序,插入排序效率最优)。

工作原理

以该数组为例
在这里插入图片描述

  • 选择合适的增量序列
    确认其为递减的,我通常设置为 gap = n/3+1。该数组中,第一次的 增量序列为3,所以后续我就以gap=3为例讲解过程

  • 根据增量序列分组
    这一步就是希尔排序的核心,我把间隔为三的元素分为一组,上述数组分组后如下图所示在这里插入图片描述
    至此数组被分为三组:[64,12,90],[34,22],[25,11],后面我简称其为增序数组

  • 依次进行插入排序
    我在排序算法入门:直接插入排序详解一文中详细介绍了插入排序,如果你尚不清楚可以参考这篇文章。这里我还是模拟一次详细过程帮你理解:
    我们用变量end表示有序区的最后一个元素,end+gap表示同组增序数组的元素
    在这里插入图片描述
    通过逻辑比较,关注end的位置,如其超出数组了代表达到数组头部。在这里插入图片描述
    你需要了解直接插入排序才能理解上述过程,因为二者没有区别。

  • 缩小增量重复过程
    缩小gap的值,直到gap==1时,其就是完全的直接插入排序

增量序列的选择

增量序列的选择有很多,不同的选择会产生不同的时间复杂度,我给出我用过的几种:

  • 希尔最初的增量序列
    规则:gap = n / 2,每次循环 gap /= 2(如 n=10 时,增量为 5, 2, 1)。
    最易理解,但效率不是最优,时间复杂度约为 O(n^2)
  • Knuth 增量序列
    由公式 gap = 3 * gap + 1 生成
    使时间复杂度优化至约O(n^1.5),是实践中较常用的序列。
  • Sedgewick 增量序列
    结合两种模式的序列:D=9∗4^i - 9∗2^i +1 或 4i−3∗2^i+1
    理论上时间复杂度接近O(n^1.3)

实现

void ShellSort(int arr[], int n)
{int gap = n;while (gap > 1) // 直到 gap==1 时,为直接插入排序{gap = gap / 3 + 1; // 修改增量序列for (int i = 0; i < n - gap; i++){	int end = i;int tmp = arr[end + gap];while (end >= 0){if (arr[end] > tmp){arr[end + gap] = arr[end];end -= gap;}else{break;}}arr[end + gap] = tmp;}}
}

分析

希尔排序是不稳定排序(相同元素的相对位置可能因 “分组排序” 改变),但平均效率优于普通插入排序。

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

相关文章:

  • 从零开始部署Qwen3-8b大模型到本地
  • Centos 安装 redis
  • 17_INIT_WORKLinux内核模块
  • prefetch 下载 GEO 数据注意事项
  • 设计模式—桥梁模式(Bridge)
  • 移动端跨平台框架(支持Harmony、iOS、Android)
  • 《第十篇》深入解析 `MilvusKBService`:基于 Milvus 的知识库服务实现
  • 在线计算“蛋白-蛋白复合物”的MM/GBSA
  • KMP算法详解及应用指南
  • Cartographer安装测试与模块开发(四)--Cartographer纯定位思路
  • 【代码随想录day 12】 力扣 102.107.199. 二叉树的层序遍历
  • 数据库设计方法详解
  • Spring之【初识AOP】
  • 应急响应linux
  • 英伟达算力卡巅峰对决:H100、A100与消费级显卡哪里找?
  • 数语科技登陆华为云商店,助力企业释放数据潜能
  • day20|学习前端
  • JavaScript 基础语法
  • 频数分布表:数据分析的基础工具
  • Adobe Analytics 数据分析平台|全渠道客户行为分析与体验优化
  • Qt 容器类详解:顺序容器与关联容器及其遍历方法
  • [LVGL] 配置lv_conf.h | 条件编译 | 显示屏lv_display
  • 组合模式(Composite Pattern)及其应用场景
  • 基于spring boot的个人博客系统
  • tkwebview-tkinter的web视图
  • 解决云服务器端口无法访问的方法
  • java学习 leetcode24交换链表节点 200岛屿数量 +一些开发任务
  • Redis(七):Redis高并发高可用(主从复制)
  • JP3-4-MyClub后台前端(二)
  • C++、STL面试题总结(三)