希尔排序及C语言实现

【算法】希尔排序C语言实现 上一篇文章我们一起学习了直接插入排序,它的原理就是把前i个长度的序列变成有序序列,然后循环迭代,直至整个序列都变为有序的.但是说来说去它还是一个时间复杂度为(n^2)的算法,难道就不能再进一步把时间复杂度降低一阶么?可能有很多同学说快速排序,堆排序,我都会,这些简单的插入排序我都不屑于用.确实,以上几种算法相对于之前的O(n^2)级别的算法真的是弱爆了,效率可能还会差上千万倍,但是我们不妨翻看一下 阅读详情

希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。

 

该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

 

以n=10的一个数组49, 38, 65, 97, 26, 13, 27, 49, 55, 4为例

第一次 gap = 10 / 2 = 5

49   38   65   97   26   13   27   49   55   4

1A                                        1B

        2A                                         2B

                 3A                                         3B

                         4A                                          4B

                                  5A                                         5B

1A,1B,2A,2B等为分组标记,数字相同的表示在同一组,大写字母表示是该组的第几个元素, 每次对同一组的数据进行直接插入排序。即分成了五组(49, 13) (38, 27) (65, 49)  (97, 55)  (26, 4)这样每组排序后就变成了(13, 49)  (27, 38)  (49, 65)  (55, 97)  (4, 26),下同。

第二次 gap = 5 / 2 = 2

排序后

13   27   49   55   4    49   38   65   97   26

1A             1B             1C              1D            1E

        2A               2B             2C             2D              2E

第三次 gap = 2 / 2 = 1

4   26   13   27   38    49   49   55   97   65

1A   1B     1C    1D    1E      1F     1G    1H     1I     1J

第四次 gap = 1 / 2 = 0 排序完成得到数组:

4   13   26   27   38    49   49   55   65   97

 

下面给出严格按照定义来写的希尔排序

[cpp]  view plain copy
  1. void shellsort1(int a[], int n)  
  2. {  
  3.     int i, j, gap;  
  4.   
  5.     for (gap = n / 2; gap > 0; gap /= 2) //步长  
  6.         for (i = 0; i < gap; i++)        //直接插入排序  
  7.         {  
  8.             for (j = i + gap; j < n; j += gap)   
  9.                 if (a[j] < a[j - gap])  
  10.                 {  
  11.                     int temp = a[j];  
  12.                     int k = j - gap;  
  13.                     while (k >= 0 && a[k] > temp)  
  14.                     {  
  15.                         a[k + gap] = a[k];  
  16.                         k -= gap;  
  17.                     }  
  18.                     a[k + gap] = temp;  
  19.                 }  
  20.         }  
  21. }  

很明显,上面的shellsort1代码虽然对直观的理解希尔排序有帮助,但代码量太大了,不够简洁清晰。因此进行下改进和优化,以第二次排序为例,原来是每次从1A到1E,从2A到2E,可以改成从1B开始,先和1A比较,然后取2B与2A比较,再取1C与前面自己组内的数据比较…….。这种每次从数组第gap个元素开始,每个元素与自己组内的数据进行直接插入排序显然也是正确的。

[cpp]  view plain copy
  1. void shellsort2(int a[], int n)  
  2. {  
  3.     int j, gap;  
  4.       
  5.     for (gap = n / 2; gap > 0; gap /= 2)  
  6.         for (j = gap; j < n; j++)//从数组第gap个元素开始  
  7.             if (a[j] < a[j - gap])//每个元素与自己组内的数据进行直接插入排序  
  8.             {  
  9.                 int temp = a[j];  
  10.                 int k = j - gap;  
  11.                 while (k >= 0 && a[k] > temp)  
  12.                 {  
  13.                     a[k + gap] = a[k];  
  14.                     k -= gap;  
  15.                 }  
  16.                 a[k + gap] = temp;  
  17.             }  
  18. }  


再将直接插入排序部分用 白话经典算法系列之二 直接插入排序的三种实现  中直接插入排序的第三种方法来改写下:

[cpp]  view plain copy
  1. void shellsort3(int a[], int n)  
  2. {  
  3.     int i, j, gap;  
  4.   
  5.     for (gap = n / 2; gap > 0; gap /= 2)  
  6.         for (i = gap; i < n; i++)  
  7.             for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap)  
  8.                 Swap(a[j], a[j + gap]);  
  9. }  

这样代码就变得非常简洁了。

  from:白话经典算法系列之三 希尔排序的实现

附注:上面希尔排序的步长选择都是从n/2开始,每次再减半,直到最后为1。其实也可以有另外的更高效的步长选择,如果读者有兴趣了解,请参阅维基百科上对希尔排序步长的说明:

http://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F

用C语言实现希尔排序 希尔排序是直接插入排序的改良版,比直接插入排序更加高效,它是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 形象地说就是像军训或者体育课初次进行排队的步骤: 教官/老师让所有人排成一队,按1 2 3 1 2 3循环报数(此时下标的一定增量就是3) 报到相同数字的就重新组成一队(分组,但事实上不会分成三组,只是逻辑上进行分组,相当于打上标记) 在每个重新组成的组里按身高进行排序(直接插入排序) 改变 阅读详情

相关推荐

稳定性定义: 各算法稳定性 一、直接插入排序   二、折半插入排序  六、简单选择排序  三、希尔排序   四、冒泡排序  五、快速排序  七、堆排序   八、归并排序 

稳定性定义:排序前后两个相等的数相对位置不变,则算法稳定。 稳定性得好处:从一个键上排序,然后再从另一个键上排序, 举个例子: 在数据库操作中,如下简单表格: 2(1) 4 3 8 2(2) 5 1 2 4 9 上表格第一个列,如果需要第一列排序,且使用稳定排序算法可得到 1 22(1) 4 2(2) 5 3...

ZhangJiqun&191cm&85kg 1062

白话经典算法系列之三 希尔排序的实现

希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。   该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增

MoreWindows Blog 22万+

C语言实现希尔排序

希尔排序是一种基于插入排序的算法,通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。这种算法交换操作结合了直接插入排序和分组交换的思想,交换操作和移动操作相结合,相比于直接插入排序,希尔排序交换操作和移动操作相结合,效率更高。希尔排序是非稳定排序算法。希尔排序是对直接插入排序的优化。当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。

qq_74013365的博客 1679

6-1 希尔排序的实现

#include<stdio.h> #include<stdlib.h> typedef int KeyType; typedef struct { KeyType *elem; /*elem[0]一般作哨兵或缓冲区*/ int Length; }SqList; void CreatSqList(SqList *L);/*待排序列建立,由裁判实现,细节不表*/ vo

gyp0205的博客 1441

C语言实现希尔排序算法详解

htmltable {th, td {th {pre {简介:希尔排序是一种效率较高的排序算法,尤其适用于大规模数据。它基于插入排序,通过选择合适的间隔序列对数组进行分组排序,然后逐步减小间隔,直至为1,完成最终排序。C语言实现希尔排序需要理解插入排序原理和间隔序列概念,并通过编写和shell_sort函数来完成算法步骤。该算法优化了元素交换次数,使时间复杂度在平均情况下达到O(n log n)。

weixin_42418754的博客 564

从时频谱图到智能感知:雷达信号处理的AI进化之路

本文探讨了人工智能在雷达信号处理中的革命性应用,特别是深度学习在时频谱图分析中的突破性进展。通过对比传统信号处理方法与AI驱动的解决方案,展示了CNN、3D CNN等模型在目标检测、行为识别等场景中的优势,并分析了数据获取、模型优化等关键技术挑战。AI赋能的雷达技术已广泛应用于智能交通、工业检测和医疗健康领域,展现出巨大的发展潜力。

weixin_29284201的博客 507

SDUTACM 数据结构实验之排序六:希尔排序

题目描述 我们已经学习了各种排序方法,知道在不同的情况下要选择不同的排序算法,以期达到最好的排序效率;对于待排序数据来说,若数据基本有序且记录较少时, 直接插入排序的效率是非常好的,希尔排序就是针对一组基本有序的少量数据记录进行排序的高效算法。你的任务是对于给定的数据进行希尔排序,其中增量dk=n/(2^k)(k=1,2,3……) 输入 连续输入多组数据,每组输入数据的第一行

Key_MQL的博客 727

calibration的“前世今生”——从simulink开发到CANape的XCP标定

整体思路 备注: elf可简单的看作为hex和map的集合,其中包括可执行的程序、变量及其对应的地址(simulink生成代码是也可以勾选生成ASAP2的a2l文件,有变量但变量对应的地址为空,只有编译后才分配地址) 定义变量是观测值还是标定值需要在simulink中的数据字典定义变量存储类型,详见simulink系列。 1. 前期准备A2L的制作 安装完成CanApe软件 , 插上CanApe硬件( 如:vector 1640A)。打开A2L编辑软件 ASAP2 Editor(注意不是ASAP2 Vi

IHTY_NUI的博客 1万+

详解希尔排序的实现

希尔排序是简单插入排序的改进版本,也称为缩小增量排序。实现思想: 将待排序数据分成若干组(gap组),每组内的数据是不连续的,是间隔了一定“增量”的,然后对每组数据进行简单插入排序,使得待排序的全部数据大概有序,再依次缩减增量进行插入排序,知道全部数据基本有序(组内数据的增量足够小的时候),最后再对全部数据进行一次简单插入排序(只有一组),即可完成排序 (注:简单插入排序是数据越有序越快)如下图

Zj_boring的博客 814

Silvaco TCAD仿真4——DeckBuild实战:从示例库到自定义设计

本文详细介绍了Silvaco TCAD仿真工具DeckBuild的实战应用,从示例库的使用到自定义设计的全过程。通过具体案例和参数修改技巧,帮助用户快速掌握TCAD仿真技术,提升半导体器件设计的效率和精度。特别适合需要从基础入门到进阶操作的工程师和研究人员。

weixin_29284657的博客 434

Android SELinux——neverallow问题处理(十六)

遇到 neverallow 规则问题,千万别急着去注释/剔除里面原有的规则(原生的尽量别动)。增加 allow 规则是常见的解决办法,但是随着 android 版本的升级,系统对 SELinux 的管控越来越严,增加了大量的 neverallow。一般情况下,向默认标签授予权限的做法是错误的,其中许多权限都是 neverallow 规则所不允许的。按照上面方法去添加 SELinux 可能会违反了 neverallow 规则,编译时候会报 neverallow 相关的错误。

小旭的专栏 2671

希尔排序(C语言实现)

排序算法

m0_59083833的博客 1万+

某东x-api-eid-token风控参数分析与破解

x-api-eid-token是京东的风控参数,在接口当中,如果没有该参数,有一定的概率能请求成功,但是在请求一段时间后,会报403权限失败的,该参数主要通过jsTk.do这个接口生成,并且会将其存储到cookie当中。

zhouzhou_98的博客 1552

图解希尔排序C语言实现

本文基于C语言实现希尔排序,使用图解方式演示希尔排序算法原理。

kevin1499的博客 930

图文详解Trae配置Java开发环境

本文介绍了Trae开发工具的安装配置流程:首先从官网下载安装Trae,然后安装Java开发所需的Extension Pack for Java和Spring Boot Extension Pack插件。关键步骤包括修改settings.json配置文件,需指定JDK路径、Maven可执行文件路径和用户设置文件路径。所有操作均配有图示说明,并强调要替换为实际电脑路径。

谷哥的小弟 5992

SAP UI5 SimpleForm 的本质、布局选择与工程化用法:从 API 到 Fiori 规范的完整解析

SimpleForm的价值在于让开发者以“语义顺序”来思考表单:分组—行—字段,由此把更多精力放在表单信息架构与Fiori规范的落地上。当你理解了开分组、Label开新行、的断点与比例、的对齐特性、editable与的真实含义,就能据此为每个页面挑选合适的布局与参数,构建既合规又具备高可读性的企业级表单。新分组、Label新行、其他控件归当前行。SAP的断点、比例与的要点来自Fiori设计文档。SAP的适用性来自样例与课程的推荐,列表类控件不应作为其行内容。某些旧属性仅在生效,应避免误用。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 300

ShellSort(希尔排序)——C语言实现

希尔排序 缩小增量排序 ShellSort

ctz6d1p的博客 877

使用MATLAB的COMSOL LiveLink:实时连接和数据传输

COMSOL LiveLink是一种功能强大的MATLAB工具包,它允许用户在MATLAB环境中与COMSOL Multiphysics软件进行实时连接和数据传输。COMSOL LiveLink是一种功能强大的MATLAB工具包,它允许用户在MATLAB环境中与COMSOL Multiphysics软件进行实时连接和数据传输。使用COMSOL LiveLink,你可以进行更复杂的模型设置和数据传输使用MATLAB的COMSOL LiveLink:实时连接和数据传输。

PixelNinja的博客 2089

希尔排序算法的C语言实现

希尔排序的介绍这里就不赘述了,网上有很多。直接上代码,代码在CODEBLOCKS测试通过。 void array_print(int *array,int num) { int i; for(i = 0;i < num; i++) printf("%d\t",array[i]); printf("\n"); return; } ...

熊果屋的博客 340

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

希尔排序c语言实现

希尔排序c语言实现

阿常呓语的专栏 2647

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C语言实现插入排序——希尔排序算法

C语言实现希尔排序 文章目录C语言实现希尔排序希尔排序算法项目完整代码运行效果图 希尔排序算法 //希尔排序算法 void ShellSort(int arr[], int len) { int d, i, j; //arr[0]只是暂存单元,不是哨兵,当j<=0时,表示到达插入位置 for (d = len / 2; d >= 1; d /= 2) { //步长变化,每次取一半 for (i = d + 1; i <= len; +

酒醉浮生的博客 1760

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: 计算机网络面试题(一)
下一篇: 冒泡排序的三种实现
vic__vic
博客等级 码龄15年 3粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值