希尔排序

一:基本思想

先选定一个整数gap,把待排序文件中所有记录分成个组,按照所有距离为整数gap的记录分在同一组内,并对每一组内的记录进行排序。然后,通过整数gap逐渐变小,重复上述分组和排序的工作。当整数gap变小到达=1时,也就是执行插入排序,这样所有记录在统一组内就排好序了

所以一定得先理解:插入排序-CSDN博客

不然很难理解此博客 

二:预排序的意义

Q:既然最后都要执行插入排序,那多一步预排序,不是会徒增运算了

A:预排序的意义在于让最后一步的插入排序的运算量大大的减小,比直接的单独的插入排序更优

三:预排序的核心

正如希尔排序的思想,我们需要一个整数gap,这个整数gap会逐渐变小,最终变小到1为止

一般是gap 初始化为N,也就是数组的元素个数,然后在循环中 gap= gap/2 ,这样每次进入循环这个gap就 /2,会逐渐的减小,最终为1(跟着除法原则,一个大于2的数不断的/2,一定会有一次为1)

例子:

 解释:

1:

gap = N(10);

gap = gap/2 = 5;

根据思想可知:gap为5,即按照所有距离(下标差值)为5的记录分在同一组内,如图内的:

第一组:9 4

第二组:1 8

第三组:2 6

第四组:5 3

第五组:7 5

然后每组进行组内的排序:

第一组:4 9

第二组:1 8

第三组:2 6

第四组:3 5

第五组:5 7

也就是上图中的:

2:

gap = gap/2 = 2;

此时的gap变成2,所以:

第一组:4 2 5 8 5

第二组:1 3 9 6 7

然后进行每组的组内排序:

第一组:2 4 5 5 8

第二组:1 3 6 7 9

也就是上图中的:

3:

 gap = gap/2 = 1;

gap为1:

只有一组:2 1 4 3 5 6 5 7 8 9

组内排序后:

1 2 3 4 5 5 6 7 8 9

也就是上图中的:

说白了gap为1 的时候,进行的就是一次插入排序,而且可以看的出来,最后一次插入排序之前 ,我们接收到的数组已经有了一定的顺序。

下面是博主找到的一个动态演示图:不过数据和上面的不一样,一样的也是gap =5 到 gap = 2再到最后的 gap =1:

四:代码展示

//希尔排序的第一种写法(双for)
void ShellSort(int* arr, int N)
{//gap初识为N,元素的个数int gap = N;//gap不为1就要继续的缩小并排序while (gap > 1){//gap缩小gap = gap / 2;//这个for控制每组的元素for (int j = 0; j < gap; j++){	//这个for控制每组内的排序for (int i = j; i< N - gap; i += gap){int end = i;//即将排序的元素,保留在tmpint tmp = arr[end + gap];//end>=0代表还有元素未比较while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];end -= gap;}else{break;}//来到这里分为两种情况 //1:break->遇到比元素tmp小或和tmp相等的,将m放在它的后面//2:全部比较完了,都没有遇到<=tmp的,最后tmp放在数组第一个位置arr[end + gap] = tmp;}}}}
}

解释:

1:跟纯粹的插入排序相比,咱们多了一个控制每组的元素的for循环 ,以及多了一个while来确保gap最后为1执行完排序才终止

2:第二个for循环:

该for循环控制的是每组元素的内部排序,可以看作插入排序,不过元素是间隔的!i<N-gap和插入排序中的i<N-1意义一致,在插入排序中我们最后的end(i)要停留在倒数第二个元素是,下标为N-2,所以end才<N-1,才能取到N-2。所以们这里i<N-gap,也是为了确保end停留在倒数第二个元素上。

3:第一个for循环:

该for控制的是每组的元素,gap为5,数组被分成了5组,j会每次都赋给end,这样end的起始位置不同,也就进行的组的更换,再在第二个for中进行组内的排序:

如图所示:

 gap为5的最终结果:

然后gap就会变小,进行新一轮的分组排序,最后gap =1 的那一次的分组排序执行完,就获得了一个有序的数组,这就是希尔排序。

希尔排序还有另一种写法:

//单for
void ShellSort(int* arr, int N)
{//gap初识为N,元素的个数int gap = N;//gap不为1就要继续的缩小并排序while (gap > 1){//gap缩小gap = gap / 2;for (int i= 0; i< N - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];end -= gap;}else{break;}arr[end + gap] = tmp;}}}}

第一种写法是:分一组,排序一组,然后再去分一组,再排序

第二种写法是:多组并排,也就是直接对数组选择性的进行排序

如图:

end =1 就进行①的两个元素的排序,以此类推

最后得到:

然后再进行gap的缩小,进行新一轮的排序

个人觉得双for循环的写法更加的易懂 

五:效果测试

六:与插入函数的比较

相信很多人都并觉得希尔比插入好,下面进行比较运算的时间(单位ms)来展示希尔的强大:

测一万个随机数,插入排序花了6ms,希尔花了1ms

  

 测十万个随机数,插入排序花了0.6秒,希尔花了9ms

测一百万个随机数,插入排序花了63秒,希尔花了0.1秒,我就问你屌不屌?? 

七:一些容易出错的细节

1:gap = gap/2,对于N比较大的时候不太够看,建议gap = gap/3+1,+1是为了确保gap可以为1

2:千万不要觉得end 的值 要经过 i 的复制,感觉太过麻烦,直接把end写在for循环那里,这样会造成 end在for循环中改变自己大小,控制不住 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/879059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python全网最全基础课程笔记(七)——列表,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!

本专栏系列为Pythong基础系列&#xff0c;每篇内容非常全面&#xff0c;包含全网各个知识点&#xff0c;非常长&#xff0c;请耐心看完。 每天都会更新新的内容&#xff0c;搜罗全网资源以及自己在学习和工作过程中的一些总结&#xff0c;可以说是非常详细和全面。 以至于为什么…

怎样给U盘加密?看这里!30s学会四种方法,保护你的数据安全!

在一家中型科技公司里&#xff0c;一名员工将包含重要项目资料的U盘遗忘在咖啡店的桌子上。该U盘内存有公司尚未公开的新产品设计图纸、客户信息以及财务报告等敏感数据。几小时后&#xff0c;这个未加密的U盘被一名陌生人拾到并插入其电脑中查看&#xff0c;机密信息被上传到网…

erlang学习: Mnesia Erlang数据库

创建Mnesia数据库 mnesia:create_schema([node()]).在shell里输入该行代码即可创建一个mnesia数据库于当前文件夹下 编译器文件路径下同样也有 数据库表定义创建 之后是数据库表定义&#xff0c;打开数据库创建完成后&#xff0c;启动数据库&#xff0c;添加一些表定义&…

Ubuntu22.04安装nginx

1.安装nginx 首先&#xff0c;更新你的包索引&#xff1a; sudo apt update 安装必要的软件包以允许apt通过HTTPS使用仓库&#xff1a; sudo apt install ca-certificates curl gnupg lsb-release 添加Nginx官方的GPG密钥&#xff1a; curl -fsSL https://nginx.org/keys/ng…

JavaScript练手小技巧:利用鼠标滚轮控制图片轮播

近日&#xff0c;在浏览网站的时候&#xff0c;发现了一个有意思的效果&#xff1a;一个图片轮播&#xff0c;通过上下滚动鼠标滚轮控制图片的上下切换。 于是就有了自己做一个的想法&#xff0c;顺带复习下鼠标滚轮事件。 鼠标滚轮事件&#xff0c;参考这篇文章&#xff1a;…

Vue如何将网页转换成图片或PDF并上传

一.使用html2canvas获取页面元素并绘制成图片 htmlcanvas中文文档 npm install --save html2canvas<template><div><button click"uploadImg">上传</button><div ref"yourDom"><!-- ...图片中页面内容 --><img s…

【Linux】多线程:线程互斥、互斥锁

目录 一、多线程访问公共资源时所产生的问题 二、互斥相关背景概念 互斥量mutex&#xff08;锁&#xff09;的引入 三、互斥量 1、初始化互斥量&#xff08;mutex&#xff09; 2、互斥量加锁 3、互斥量解锁 4、 销毁互斥量 四、互斥量的使用 1、使用静态互斥量 2、…

安泰功率放大器在微纳光固化3D打印中的具体应用

随着科技的进步&#xff0c;3D打印技术已经渗透到各个领域&#xff0c;尤其是微纳光固化3D打印技术。这种技术结合了光学、材料科学和微电子学的知识&#xff0c;能够制造出具有微米级精度的复杂物体。本文Aigtek安泰电子将带你探索功率放大器在微纳光固化3D打印中的应用&#…

OpenCV 之 模版匹配多个对象、图片旋转 综合应用

引言 在图像处理和计算机视觉中&#xff0c;模板匹配是一种常用的技术&#xff0c;用于在一幅较大的图像中查找与给定模板图像相似的部分。然而&#xff0c;在实际应用中&#xff0c;目标物体可能会出现在不同的角度&#xff0c;这就需要我们在匹配之前对模板进行旋转处理。本…

仿某皮影狸app官网源码 不错的APP下载官网单页源码 HTML源码

分享一款不错的APP下载官网单页源码&#xff0c;直接修改index.html即可 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89731228 更多资源下载&#xff1a;关注我。

Python(PyTorch和TensorFlow)图像分割卷积网络导图(生物医学)

&#x1f3af;要点 语义分割图像三层分割椭圆图像脑肿瘤图像分割动物图像分割皮肤病变分割多模态医学图像多尺度特征生物医学肖像多类和医学分割通用图像分割模板腹部胰腺图像分割分类注意力网络病灶边界分割气胸图像分割 Python生物医学图像卷积网络 该网络由收缩路径和扩…

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测+交叉验证

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证 目录 回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于贝叶…

AI大模型精准升级!揭秘高级RAG架构,让回答更精准、更可靠!

什么是 RAG&#xff1f; 当然&#xff0c;本文依然会讲解一部分 RAG 的基础知识&#xff0c;让你能够对文章的上下文有个初步了解。 “检索增强生成” (Retrieval Augmented Generation)&#xff0c;简称 RAG&#xff0c;这一概念首次出现在 2020 年 Meta 发布的一项学术研究…

中国《人工智能安全治理框架》1.0版正式发布 规范各类AI、算法

今日&#xff0c;全国网络安全标准化技术委员会发布《人工智能安全治理框架》1.0版。《框架》提出了包容审慎、确保安全&#xff0c;风险导向、敏捷治理&#xff0c;技管结合、协同应对&#xff0c;开放合作、共治共享等人工智能安全治理的原则。 针对模型算法安全、数据安全和…

RK3576芯片在智能家居里中型智慧屏产品的应用方案分析

智能家居在近年来得到了快速发展&#xff0c;AI技术不断发展&#xff0c;人机交互十分成熟&#xff0c;各种家电也都迎来了智能化浪潮&#xff0c;智能家居为人们提供了优秀的产品体验&#xff0c;受到主流消费者的青睐&#xff0c;智能家居里的中型智慧屏产品也随之兴起。 瑞芯…

RedisTemplate操作String的API

文章目录 1 String 介绍2 命令3 对应 RedisTemplate API❄️❄️ 3.1 添加缓存❄️❄️ 3.2 设置过期时间(单独设置)❄️❄️ 3.3 获取缓存值❄️❄️ 3.4 删除key❄️❄️ 3.5 顺序递增❄️❄️ 3.6 顺序递减 ⛄4 以下是一些常用的API⛄5 应用场景 1 String 介绍 String 类型…

anaconda启动jupyter notebook

1.在Windows搜索框搜索anaconda prompt点击打开 2.然后输入命令jupyter notebook 3.在这个页面编写你的程序

MATLAB实现PID参数自动整定

目录 1、项目说明 2、文件说明 1、项目说明 本项目旨在通过 MATLAB 语言实现 PID 参数的自动整定&#xff0c;并设计了一个直观易用的 GUI 界面。该系统特别适用于实验室环境下的 PID 参数自整定任务。整定的核心原则在于优化系统性能&#xff0c;使系统的衰减比尽可能接近理…

2025考公最新视频免费分享花生十三、齐麟、葛欣、阿里木江、龙飞、袁东、飞扬、李梦娇等

&#x1f389;备战公考不用愁&#xff0c;我的小程序为你助力&#x1f389; 这里汇聚了花生十三、齐麟、葛欣、阿里木江、龙飞、彬彬、袁东、飞扬、李梦娇、高照等几十位公考名师。他们的视频课程精彩纷呈&#xff0c;搭配详细讲义&#xff0c;让你轻松掌握公考要点。 作为一…

Java | Leetcode Java题解之第395题至少有K个重复字符的最长子串

题目&#xff1a; 题解&#xff1a; class Solution {public int longestSubstring(String s, int k) {int ret 0;int n s.length();for (int t 1; t < 26; t) {int l 0, r 0;int[] cnt new int[26];int tot 0;int less 0;while (r < n) {cnt[s.charAt(r) - a];…