news 2026/5/1 9:55:22

希尔排序--自学笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
希尔排序--自学笔记

希尔排序

学习目标:

一.希尔排序的思想

二.增量序列

三.复杂度分析

四.希尔排序为什么快?

五.强化练习

一.希尔排序的思想

1.将待排序数组按照一定的“间隔”分为多个子数组,

每组分别进行“插入排序”

2.逐渐缩小间隔,进行下一轮排序

3.最后一轮时,取间隔为1,相当于直接使用插入排序

但此时经过 [宏观调控] 数组已经基本有序

所以此时插入排序只需进行少量交换

代码实现
publicstaticvoidshellSort(int[]arr){for(intgap=arr.length/2;gap>0;gap/=2){for(intgroupStartIndex=0;groupStartIndex<gap;groupStartIndex++){for(intcurrentIndex=groupStartIndex+gap;currentIndex<arr.length;currentIndex+=gap){intcurrentNumber=arr[currentIndex];intpreIndex=currentIndex-gap;while(preIndex>=groupStartIndex&&arr[preIndex]>currentNumber){arr[preIndex+gap]=arr[preIndex];preIndex-=gap;}arr[preIndex+gap]=currentNumber;}}}}

目前的思路是,根据gap分组,处理完一组后,调整指针,再处理下一组

这种思路非常符合人类思维,但对于计算机而言,它更喜欢

从gap开始,依次向前,将每个数字插入到其对应的组中,

虽然数字好像在不同组间跳跃,但对于计算机就像是在访问一段连续的数组

代码优化

将第二、三个for循环整合成一个

publicstaticvoidshellSort(int[]arr){for(intgap=arr.length/2;gap>0;gap/=2){for(intcurrentIndex=gap;currentIndex<arr.length;currentIndex++){intcurrentNumber=arr[currentIndex];intpreIndex=currentIndex-gap;while(preIndex>=0&&arr[preIndex]>currentNumber){arr[preIndex+gap]=arr[preIndex];preIndex-=gap;}arr[preIndex+gap]=currentNumber;}}}

二.增量序列

1.定义

Shell排序中,每一遍排序的间隔 ‘gap’ 被称为 “增量” ,所有增量组成的序列叫做增量序列

也就是上述例子中的’5‘,’2‘,’1‘,增量是依次递减

所以Shell排序又称为缩小增量排序

增量序列的选择会极大影响Shell排序的效率!

若没有正确选择增量序列,Shell排序效率可能比插入排序更低!

如图所示,在gap = 8 , 4 , 2 时无元素交换,只有在gap = 1时才发挥了作用

而此时Shell排序相比插入排序,多做了无用功

2.一些著名的增量序列

(1) Hibbard增量序列

Dk= 2k- 1 , 也就是 1,3,7,15,… 。

数学界猜想它最坏的时间复杂度为O(n3/2) ,

平均时间复杂度为O(n5/4)

(2) Knuth增量序列

D1= 1; Dk+1= 3 * Dk+ 1,也就是 1,4,13,40,… 。

数学界猜想它的平均时间复杂度为O(n3/2)

(3) Sedgewick增量序列

1,5,19,41,109,… 。

这个序列的元素有的是通过 9 * 4k- 9 * 2k+ 1 计算出来的

有的是通过 4k- 3 * 2k+ 1 计算出来的

并将其按照从小到大排列

数学界猜想它最坏的时间复杂度为O(n4/3)

平均时间复杂度为O(n7/6)

3.增量序列示例

publicstaticvoidshellSort(int[]arr){//使用Knuth增量序列//先要找出增量序列的最大值intmaxKnuthNum=1;//初始化while(maxknuthNum*3+1<arr.length){maxKnuthNum=maxknuthNum*3+1}//把值赋给gap,并修改gap变化的规律for(intgap=maxknuthNum;gap>0;gap=(gap-1)/3){for(intcurrentIndex=gap;currentIndex<arr.length;currentIndex++){intcurrentNumber=arr[currentIndex];intpreIndex=currentIndex-gap;while(preIndex>=0&&arr[preIndex]>currentNumber){arr[preIndex+gap]=arr[preIndex];preIndex-=gap;}arr[preIndex+gap]=currentNumber;}}}

三.复杂度分析

由于增量序列会极大影响Shell排序的效率

时间复杂度:平均时间复杂度介于O(n)到O(n2)

​ 普遍认为最好的时间复杂度为O(n1.3)

空间复杂度:O(1) 只需要常数级的临时变量

四.希尔排序为什么快?

1.“逆序对”概念引入

当我们从小到大排序时,在数组中的两个数字,如果前面一个数字大于后面的数字

则这两个数字组成一个逆序对

而所有排序算法的本质都是:消除逆序对

对于随机的数组,逆序对的数量是O(n2)级的

如果使用交换相邻元素的方法来消除逆序对,每次只能消除一组逆序对

所以交换的次数是O(n2)级的

这就是冒泡、选择、插入排序算法时间复杂度只能达到O(n2)的原因

基于交换元素的排序算法 ( 空间复杂度为O(1) ) 想突破O(n2),必须通过一些比较,交换间隔比较远的元素

也就是需要在一次交换中能够消除一个以上的逆序对

Shell排序算法就是如此

此后的快排、堆排也是如此…

五.强化练习

506. 相对名次 - 力扣(LeetCode)

杂度为O(1) ) 想突破O(n2),必须通过一些比较,交换间隔比较远的元素

也就是需要在一次交换中能够消除一个以上的逆序对

Shell排序算法就是如此

此后的快排、堆排也是如此…

五.强化练习

506. 相对名次 - 力扣(LeetCode)

912. 排序数组 - 力扣(LeetCode)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 8:29:55

前端开发规范实践

文档总结了前端开发团队在代码规范、质量控制、版本管理和开发流程等方面的一些实践&#xff0c;旨在帮助团队建立统一的开发标准&#xff0c;提高代码质量和开发效率。1. 前端编码规范管理1.1 统一编码规范1.1.1 命名规范变量命名&#xff1a;使用小驼峰命名法&#xff08;cam…

作者头像 李华
网站建设 2026/5/1 8:44:47

通达信支撑线

{}GUOQI:DATE>1110101; BAOLIU:DAY>24 AND DAY<30 AND FRACPART(MONTH/2)0.5; WUXIAO:GUOQI1 AND BAOLIU1; 五分:5; 十五分:五分*3; 三十分:十五分*2; 六十分:三十分*2; 日:六十分*4; 周:日*5; 月:周*4; 季:月*3; 半年:季*2; 年:半年*2; A:(OPENHIGHLOWCLOSECLOSE)/5;…

作者头像 李华
网站建设 2026/4/24 19:29:25

通达信周均线 源码

{}TYP:(HIGHLOWCLOSE)/3; CCI:(TYP-MA(TYP,14))/(0.015*AVEDEV(TYP,14)); 陡峭度:CCI-REF(CCI,1)/1;{} RSV:(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100; K:SMA(RSV,3,1); D:SMA(K,3,1); J:3*K-2*D; REF(CCI,1)<50 AND CCI>50 AND CCI<100 AND 陡峭度>N AND …

作者头像 李华
网站建设 2026/5/1 8:42:55

技术 | 在单台电脑上管理多个 GitHub 账户并解决推送问题(测试中)

在单台电脑上管理多个 GitHub 账户并解决推送问题在日常开发中&#xff0c;我们经常需要在同一台电脑上使用多个 GitHub 账户&#xff08;例如个人账号和工作账号&#xff09;&#xff0c;但默认配置下容易出现推送权限错误或提交记录关联到错误账户的问题。本文将详细介绍如何…

作者头像 李华
网站建设 2026/5/1 9:08:01

记一次 .NET 某光放测试系统 崩溃分析

一&#xff1a;背景 1. 讲故事 微信好友里有位朋友找到我&#xff0c;说他部署在windows上的程序&#xff0c;用debug模式正常&#xff0c;但用 release 模式跑程序就崩溃&#xff0c;如果把程序切到 .NET6 的话又都正常&#xff0c;所以很迷茫&#xff0c;让我看看怎么回事&…

作者头像 李华
网站建设 2026/5/1 5:57:58

9 款 AI 写论文哪个好?实测对比后,这款全流程神器成学术党首选! 毕业论文写作季,AI 写作工具已成学子 “救命稻草”。市面上百度智能云千帆大模型、科大讯

毕业论文写作季&#xff0c;AI 写作工具已成学子 “救命稻草”。市面上百度智能云千帆大模型、科大讯飞星火认知大模型、通义千问、文心一言、ChatGPT、豆包、WPS AI、Grammarly GO、虎贲等考 AI 等 9 款主流工具扎堆&#xff0c;“9 款 AI 写论文哪个好” 成为全网热议的焦点。…

作者头像 李华