【数据结构】希尔排序(最小增量排序)
👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:数据结构
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵
希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍
目录
- 一、希尔排序的由来
- 二、算法思路
- 三、预排序代码实现
- 四、如何选择gap
- 五、代码实现(完整版)
- 六、性能分析
一、希尔排序的由来
- 从直接插入排序中,我们总结了:(假定要求升序)当原数组是逆序的时候,时间复杂度为O(N2),效率极低。博客地址:点击跳转
- 当原数组是接近升序或者已经是有序的,那么时间复杂度就是
O(N)
,此时效率最高。
因此,又一位名叫希尔的大佬发现,如果一开始就让数组内的元素接近有序的话,那插入排序的效率不就大大提升了吗?所以,希尔排序是插入排序的优化。
二、算法思路
- 预排序 — 首先让序列中的元素接近有序。
那么如何进行预排序呢?(重点)
其运用了 分组插排 的思想:定义一个变量gap
,间隔为gap
分为一组进行插入排序
- 最后再对数组进行插入排序即可。
【画图演示】
通过以上图片,我们还可以总结一个规律:gap
为几,就代表预排序有几组
接下来我们简单实现预排序的代码。
三、预排序代码实现
void ShellSort(int a[], int n)
{// 假设gap为3int gap = 3;// 1. gap是几,就代表有几组for (int i = 0; i < gap; i++){// 2. 间隔为gap为一组进行插入排序for (int j = i; j < n - gap; j += gap){// 下面基本都是插入排序的代码(类似)int end = j;int temp = a[j + gap];while (end >= 0){if (temp < a[end]){a[end + gap] = a[end];end -= gap;}else{a[end + gap] = temp;}}a[end + gap] = temp;}}
}
那么最后就要对整体进行插入排序,这样就能完美实现希尔排序了。但是我们难道还要重新再其后再手搓一个插入排序吗?理论上是可以的,但是没必要。注意看:当间隔gap
为1
时,不就是插入排序了吗?因此,普通插入排序和gap
是有关系的。那么应该如何选择gap
呢?
四、如何选择gap
gap
越大,跳的越快,越不接近有序;gap
越小,跳的越慢,越接近有序。
可以为大家验证一下:
- 当
gap = 3
时
是不是越接近有序!
- 当
gap = 5
时
虽然也接近有序,但是没有比gap = 3
更接近有序!
那么gap
到底取多少合适呢?
解答:gap
应该要不断在变化。为什么呢?开头的结论:gap
越大,跳的越快,越不接近有序;gap
越小,跳的越慢,越接近有序。如果gap
是固定大小,给大了越不接近有序,给小了接近有序,但是跳的慢。因此,预排序的为了让更大的数更快的跳到后面,越小数越快跳到前面。这就是为什么gap
应该要不断的变化。
-
最初希尔大佬提出取
gap /= 2
,为什么呢?因为一个数不断/2
,最后的结果一定为1
,那么在上面我们说过,当gap = 1
,就可以满足整体的插入排序,就不需要再手搓普通插入排序了。 -
后来
Knuth
提出取gap = gap / 3 + 1
(+1
为了保证最后gap
一定为1
),还有人提出取奇数好,也有人提出gap
互质好。但无论哪一种主张都没有得到证明。其实都是ok的
五、代码实现(完整版)
void ShellSort(int a[], int n)
{// 3. 如何取gap// gap最大可以取到整个数组的长度nint gap = n;while (gap > 1){// gap = gap / 3 + 1; // 这也是okk的gap /= 2;// 1. gap是几,就代表有几组for (int i = 0; i < gap; i++){// 2. 间隔为gap为一组进行插入排序for (int j = i; j < n - gap; j += gap){int end = j;int temp = a[j + gap];while (end >= 0){if (temp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = temp;}}}
}
【结果展示】
六、性能分析
- 时间复杂度
希尔排序的时间复杂度不好计算,因为gap
的取值方法很多,导致很难去计算。Knuth
大佬进行了大量的试验统计,计算出希尔排序的时间复杂度大约为O(N^1.3)
但是我们可以用代码进行性能测试的对比
如图,当数据个数是10w
时,插入排序和希尔排序时间效率如下所示
由此看出,希尔排序还是非常的牛逼的~
- 有人想:希尔排序在预排序的时候不是运用到很多的插入排序,为什么其效率还是比插入排序高?
原因是:其实gap
的取值决定数组内的元素是否接近有序,gap
越大,排的也越快,但越不接近有序;gap
越小,排的也就越慢,但越接近有序。所以一开始gap
的值可以设为数组元素个数(gap
一定不可能超过数组元素个数),每次进行/2
,不断缩小gap
,其实最后发现,希尔排序的插入排序的次数其实是小于直接排序的插入次数的。
相关文章:

【数据结构】希尔排序(最小增量排序)
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:数据结构 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…...
Android Native崩溃信息分析和 工具(addr2line和ndkstack)使用
这里以一个实际的crash案例未demo进行分析和讲解。针对native的崩溃信息。一般来讲,较快的方式是直接检索到backtrace,然后通过分析和使用工具addr2line和 ndk-stack等定位到出问题的地方。这里截取了一段 崩溃日志,具体如下: 01…...

2023年05月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 明明每天坚持背英语单词,他建立了英语单词错题本文件“mistakes.txt”,将每天记错的单词增加到该文件中,下列打开文件的语句最合适的是?( ) A: f = open(“mistakes.txt”) B: …...
SQLite3 数据库学习(文章链接汇总)
参考引用 SQLite 权威指南(第二版)SQLite3 入门 SQLite3 数据库学习(一):数据库和 SQLite 基础 SQLite3 数据库学习(二):SQLite 中的 SQL 语句详解 SQLite3 数据库学习(三…...

【VSCode】Visual Studio Code 下载与安装教程
前言 Visual Studio Code(简称 VS Code)是一个轻量级的代码编辑器,适用于多种编程语言和开发环境。本文将介绍如何下载和安装 Visual Studio Code。 下载安装包 首先,我们需要从官方网站下载 Visual Studio Code 的安装包。请访…...

分布式教程从0到1【1】分布式基础
1 分布式基础概念 1.1 微服务 微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署…...

Ubuntu22.04 部署Mqtt服务器
1、打开Download EMQX (www.emqx.io)下载mqtt服务器版本 2、Download the EMQX repository curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash 3.Install EMQX sudo apt-get install emqx 4.Run EMQX sudo systemctl start…...

HMM与LTP词性标注之LTP介绍
文章目录 LTP 上图缺点:参数太多,中文语料库匮乏 注意力机制,相当于给每一个词赋予一个权重,权重越大的越重要。 bert的缺点:神经元太多,较慢。 LTP 如果只是需要做词性的识别,那么用LTP就可…...

基于SSM的学生疫情信息管理系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...

分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测
分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测 目录 分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据…...

用电子签章软件怎么给标书一键签章的小故事
在这个数字化时代,电子签章已经成为了商务往来的重要一环。作为国内电子签章软件的佼佼者,微签凭借其19年的电子签研发应用经验,为中小企业提供了安全可靠的电子签章软件服务。 从审批场景到合同签署,微签都展现出卓越的电子签章…...

Windows10电脑没有微软商店的解决方法
在Windows10电脑中用户可以打开微软商店,下载自己需要的应用程序。但是,有用户反映自己Windows10电脑上没有微软商店,但是不清楚具体的解决方法,接下来小编给大家详细介绍关于解决Windows10电脑内微软商店不见了的方法,…...

SpringCloud-Gateway修改Response响应体,并解决大数据量返回不全等问题
官网相关案例: Spring Cloud Gatewayhttps://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-modifyresponsebody-gatewayfilter-factory ModifyRequestBodyGatewayFilterFactory类: https://github.com/spring-cloud/spring-cloud-gate…...
Spark与SQL之间NB的转换_withClumn,split及SubString
业务中有这样一个场景,我想实现的是将dataframe表table1中的字段b1与c1的内容使用下划线_连接起来列的名字为d1,比如比如学习_1,睡觉_2,吃饭_3,这是我的第一个需求;随后我想保留的是dataframe表table1中的字段d1中的数据比如学习_…...

修改服务器端Apache默认根目录
目标:修改默认Apache网站根目录 /var/www/html 一、找到 DocumentRoot “/var/www/html” 这一段 apache的根目录,把/var/www/html 这个目录改 #DocumentRoot "/var/www/html" DocumentRoot "/home/cloud/tuya_mini_h5/build" 二、…...

网络安全(大厂面试真题集)
前言 随着国家政策的扶持,网络安全行业也越来越为大众所熟知,想要进入到网络安全行业的人也越来越多。 为了拿到心仪的 Offer 之外,除了学好网络安全知识以外,还要应对好企业的面试。 作为一个安全老鸟,工作这么多年…...

系列五、JVM的内存结构【PC寄存器】
一、位置 CPU中 二、作用 每个线程都有一个程序计数器,是线程私有的,所谓PC寄存器其实就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引…...
ClickHouse UDF 运行速度慢问题
一、环境版本 环境版本docker clickhouse22.3.10.22 二、UDF运行速度时快时慢 udf配置文件xxx_function.xml type- 可执行类型。如果type设置为executable则启动单个命令。如果设置为,executable_pool则创建命令池。 pool_size- 命令池的大小。可选参数ÿ…...

python科研绘图:面积图
目录 1、面积图 2、堆积面积图 1、面积图 面积图是一种数据可视化图表,用于展示数据随时间或其他有序类别的变化趋势。它与折线图相似,但在展示数据变化的同时,面积图还强调了各个数据点之间的累积关系。这种图表通常通过在折线下方填充颜…...

SQL基础理论篇(六):多表的连接方式
文章目录 简介笛卡尔积等值连接非等值连接外连接自连接其他SQL92与SQL99中连接的区别不同DBMS下使用连接的注意事项参考文献 简介 SQL92中提供了5类连接方式,分别是笛卡尔积、等值连接、非等值连接、外连接(左连接、右连接、全外连接(full outer join、全连接))和自…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...

GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...