【数据结构实验】排序(二)希尔排序算法的详细介绍与性能分析
文章目录
- 1. 引言
- 2. 希尔排序算法原理
- 2.1 示例说明
- 2.2 时间复杂性分析
- 3. 实验内容
- 3.1 实验题目
- (一)输入要求
- (二)输出要求
- 3.2 算法实现
- 3.3 代码解析
- 3.4 实验结果
- 4. 实验结论
1. 引言
排序算法在计算机科学中扮演着至关重要的角色,对于数据的组织和搜索等任务有着深远的影响。希尔排序是一种插入排序的改进版本,通过引入增量的概念,能够在某些情况下显著提高排序的效率。
本文将详细介绍希尔排序算法的原理、实现,以及对其性能进行分析。
2. 希尔排序算法原理
希尔排序是一种基于插入排序的改进算法,由Donald L. Shell于1959年提出。其核心思想是将待排序的记录按下标的一定增量分组,对每组使用直接插入排序方法,随着增量逐渐减小,每组包含的记录越来越多,直至增量为1时,整个序列恰好被分成一个组,排序完成。
2.1 示例说明
考虑一个包含16个记录的输入文件,取渐减增量序列为 8 , 4 , 2 , 1 8, 4, 2, 1 8,4,2,1。初始时,将输入文件分成8个组:
- 组1: R 1 , R 9 R_1, R_9 R1,R9
- 组2: R 2 , R 10 R_2, R_{10} R2,R10
- 组3: R 3 , R 11 R_3, R_{11} R3,R11
- …
- 组8: R 8 , R 16 R_8, R_{16} R8,R16
对每个组使用直接插入排序算法进行排序。然后,取增量值为4,将文件分成4个组:
- 组1: R 1 , R 5 , R 9 , R 13 R_1, R_5, R_9, R_{13} R1,R5,R9,R13
- 组2: R 2 , R 6 , R 10 , R 14 R_2, R_6, R_{10}, R_{14} R2,R6,R10,R14
- 组3: R 3 , R 7 , R 11 , R 15 R_3, R_7, R_{11}, R_{15} R3,R7,R11,R15
- 组4: R 4 , R 8 , R 12 , R 16 R_4, R_8, R_{12}, R_{16} R4,R8,R12,R16
再次对每个组使用直接插入排序。重复这个过程,取增量值为2和1,最终完成整个排序。

2.2 时间复杂性分析
希尔排序的性能与所选取的分组长度序列密切相关。最坏情况下的时间复杂度为 O ( n 2 ) O(n^2) O(n2),但不同的分组长度序列会影响算法的实际性能。
- 当分组长度序列取 n 2 i \frac{n}{2^i} 2in时,最坏情况下时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 实际应用中,取2.2作为递减因子效果更好。
- 当分组长度序列取形如 2 p 3 q 2^p3^q 2p3q且小于n的所有正整数的集合时,希尔排序的时间复杂度为 O ( n ⋅ ( log 2 n ) 2 ) O(n \cdot (\log_2 n)^2) O(n⋅(log2n)2)。
1969年,V. Pratt证明了以上结论。目前已知的最好分组长度序列是 { 1 , 4 , 10 , 23 , 57 , 132 , 301 , 701 , 1750 , . . . } \{1, 4, 10, 23, 57, 132, 301, 701, 1750, ... \} {1,4,10,23,57,132,301,701,1750,...},具有此分组序列的希尔排序比插入排序和堆排序要快。在小数组情况下比快速排序快,但对于大数组则可能比快速排序慢。此外,希尔排序是不稳定的排序算法。
3. 实验内容
3.1 实验题目
以{7,5,3,1}为渐减增量序列实现希尔排序算法 ShellSort.
(一)输入要求
第一组输入数据:
{27,32,33,21,57,96,64,87,14,43,15,62,99,11}
第二组输入数据:
{11,14,15,21,27,32,33,43,57,62,64,87,96,99}
第三组输入数据:
{99,96,87,64,62,57,43,33,32,27,21,15,14,11}
(二)输出要求
对每组输入数据,输出以下信息(要求必须要有关于输出数据的明确的提示信息):
- 输出整个排序过程总的关键词比较次数和总的记录移动次数;
- 每发生一次记录插入,输出整个文件一次;
- 输出增量为 7、5、3、1 时的关键词比较次数和记录移动次数
3.2 算法实现
#include <stdio.h>
#define n 14
void ShellSort(int R[n]){int r,i,j,k,Compare=0,Move=0;int d=7; //初始化增量值为7while(d>0){ //不断分组,并对各组排序int compare=0,move=0;for(i=d;i<n;i++){ //对各组做直接插入排序r=R[i];j=i;while(j>d-1&&R[j-d]>r){compare++;R[j]=R[j-d];j-=d;}if(j!=i){move++;R[j]=r;for(k=0;k<n;k++){printf("%d ", R[k]);}printf("\n");} }printf("\n增量值为%d时的关键词比较次数是%d,记录移动次数是%d\n\n",d,compare,move);d=d-2; //计算新的增量值,{7,5,3,1}Compare+=compare;Move+=move;}printf("关键词的总比较次数是%d,总的记录移动次数是%d\n",Compare,Move);
}
int main(){int i;//int R[n]={27,32,33,21,57,96,64,87,14,43,15,62,99,11};int R[n]={11,14,15,21,27,32,33,43,57,62,64,87,96,99};//int R[n]={99,96,87,64,62,57,43,33,32,27,21,15,14,11};ShellSort(R);printf("最后结果:");for(i=0;i<n;i++){printf("%d ",R[i]);}
}
3.3 代码解析
- 宏定义
#define n 14
定义宏 n,表示数组的长度为14,在后续代码中可以方便地使用 n 来表示数组的长度,而不需要硬编码。
-
希尔排序函数
参数是一个整型数组R,表示待排序的数组。在函数内部,通过不断缩小增量的方式,对数据进行插入排序。具体来说,在每一轮循环结束后,更新增量的值,采用一定的方式递减。这里选择减小2的增量序列{7, 5, 3, 1}。int d = 7; while (d > 0) {// ...d=d-2; //计算新的增量值,{7,5,3,1}// ... }使用
while循环,不断缩小增量d,并在每一轮循环中进行插入排序。增量的选择是关键,这里初始设置为7,然后逐渐减小。for (i = d; i < n; i++) { // ... }针对每个分组,从第
d个元素开始,进行插入排序。while (j > d - 1 && R[j - d] > r) { // ... }在插入排序的过程中,通过比较和移动元素,确保分组内的元素是有序的。
-
输出结果
printf("\n增量值为%d时的关键词比较次数是%d,记录移动次数是%d\n\n", d, compare, move);
在每一轮排序结束后,输出该轮排序的比较次数和记录移动次数,从而了解算法在不同步长下的性能。
printf("关键词的总比较次数是%d,总的记录移动次数是%d\n", Compare, Move);
在整个排序完成后,输出总的比较次数和记录移动次数,提供了算法整体性能的信息。
- 主函数
int main(){int i;// int R[n]={27,32,33,21,57,96,64,87,14,43,15,62,99,11};// int R[n]={11,14,15,21,27,32,33,43,57,62,64,87,96,99};int R[n]={99,96,87,64,62,57,43,33,32,27,21,15,14,11};ShellSort(R);printf("最后结果:");for(i=0;i<n;i++){printf("%d ",R[i]);}
}
创建一个包含14个元素的数组 R,并调用 ShellSort 函数对其进行排序。最后输出排序后的数组。
3.4 实验结果



4. 实验结论
希尔排序是一种高效的排序算法,通过引入增量的方式,能够在某些情况下显著提高插入排序的性能。选择合适的分组长度序列对算法的实际效果有重要影响,而已知的最佳序列 { 1 , 4 , 10 , 23 , 57 , 132 , 301 , 701 , 1750 , . . . } \{1, 4, 10, 23, 57, 132, 301, 701, 1750, ... \} {1,4,10,23,57,132,301,701,1750,...}在实践中表现优异。
需要注意的是,希尔排序是不稳定的排序算法。在实际应用中,根据数据规模和特性选择不同的排序算法是很重要的,希尔排序在一些场景下可能比其他排序算法更适用。希尔排序的性能对于分组长度序列的选择非常敏感,因此在实际使用中需要根据具体情况进行调优。
相关文章:
【数据结构实验】排序(二)希尔排序算法的详细介绍与性能分析
文章目录 1. 引言2. 希尔排序算法原理2.1 示例说明2.2 时间复杂性分析 3. 实验内容3.1 实验题目(一)输入要求(二)输出要求 3.2 算法实现3.3 代码解析3.4 实验结果 4. 实验结论 1. 引言 排序算法在计算机科学中扮演着至关重要的角色…...
微信小程序开发者工具] ? Enable IDE Service (y/N) ESC[27DESC[27C
在HBuilder运行微信小程序开发者工具报错 如何解决 打开微信小程序开发者工具打开设置--->安全设置--->服务器端口选择打开就可以啦...
【数据结构】E : 货币套汇(图路径)
E : 货币套汇(图路径) Description 套汇是指利用货币汇兑率的差异将一个单位的某种货币转换为大于一个单位的同种货币。例如,假定1 美元可以买0.7 英镑,1 英镑可以买9.5 法郎,1法郎可以买到0.16美元。通过货币兑换&a…...
图书管理系统源码,图书管理系统开发,图书借阅系统源码SqlHelper数据库访问操作方法简述
SqlHelper 是封装了数据库操作方法的类库,使用它我们可以链接数据库操作数据库表数据增删改查,其中主要SqlConnection ,ExecuteNonQuery,ExecuteScalar,ExecuteDataTable四个主要方法SqlConnection负责根据访问配置文件web.config中connstr链接数据库字符串去打开数据库,…...
富文本编辑器的实现与回显
文本编辑器实现-wangeditor 写之前记得安装wangeditor插件,到时候报错别赖我 import “wangeditor/editor/dist/css/style.css”; import { Editor, Toolbar } from “wangeditor/editor-for-vue”; defineOptions({name: "BaseEditor" });const mode …...
探索亚马逊云科技云存储服务的性能
文章作者:Libai 引言 随着企业越来越多地依赖云存储解决方案,确保存储性能的最佳状态变得至关重要。在本文中,我们将探讨在亚马逊云科技云存储服务上进行存储性能基准测试的重要性,以及如何帮助企业做出资源分配和优化的明智决策…...
初出茅庐的小李博客之C语言必备知识共用体
C语言必备知识共用体 共用体是一种构造数据类型,有时候也称之为联合体。 它的用途: 使几个不同类型的变量共占一段内存。 共用体举例 union 共用体名 { 类型标识符 成员名;类型标识符 成员名; };union data //共用体名字是data{ int i; …...
vue3+elementPlus之侧边菜单栏功能
选择默认的颜色,将代码拷贝至<el-aside>模块中 稍微把不需要的修改一下。 <template><div class"common-layout"><el-container><el-header class"homeHeader"><div class"headerTitle">Devops…...
阿里云服务器安装mysql数据库之后无法远程连接
目录 一、mysql安装完成后直接远程远程连接阿里云服务器上的MySQL会报下述错误: 1、修改root用户的host 为% 登录MySQL 后 执行 2、修改完成后执行 3、退出mysql 重启mysql服务 exit; 4、修改完成后需要设置阿里云的安全规则。 二、dbaver测试链…...
如何把自己银行卡里的钱转账充值到自己支付宝上?
原文来源:https://www.caochai.com/article-4524.html 支付宝余额是支付宝核心功能之一,主要用于网购支付、线下支付、转账等场景。用户可以将银行卡、余额宝等资金转入或转出至支付宝余额,实现快速转账和支付。 如何把自己银行卡里的钱转账…...
Flink Flink中的分流
一、什么是分流 所谓“分流”,就是将一条数据流拆分成完全独立的两条、甚至多条流。也就是基于一个DataStream,定义一些筛选条件,将符合条件的数据拣选出来放到对应的流里。 二、基于filter算子的简单实现分流 其实根据条件筛选数据的需求…...
传输层协议[精选]
网络: 跨主机通信. 互联网通信: 两点之间的通信路径有无数条. 集线器: 把一根网线差出来两根,但是同一时刻只能有一根线跑.交换机: 组建局域网.路由器: 本质就是将两个局域网连接起来 交换机和路由器之间的区别越来越模糊. 调制解调器: 使用电话线上网的时候,需要将电话线的模…...
LeetCode算法题解|474. 一和零
474. 一和零 题目链接:474. 一和零 题目描述 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子…...
一种太阳能风能市电互补路灯方案介绍
太阳能市电互补路灯是一种环保、节能的照明设施,它利用太阳能进行发电并实现照明。这种路灯在白天吸收阳光并将其转化为电能,到了晚上则利用储存的电能为LED灯提供电力,实现照明功能。下面叁仟智慧将详细介绍太阳能市电互补路灯灯的工作原理和…...
世微 dc-dc降压恒流 LED汽车大灯 单灯 14V5A 68W车灯驱动方案 AP5191
产品描述 AP5191是一款PWM工作模式,高效率、外围简单、外置功率MOS管,适用于4.5-150V输入的高精度降压LED恒流驱动芯片。输出最大功率150W,最大电流6A。AP5191可实现线性调光和PWM调光,线性调光脚有效电压范围0.55-2.6V.AP5191 工作频率可以…...
基于时隙的多重冗余流指纹模型
文章信息 论文题目:基于时隙的多重冗余流指纹模型 期刊(会议):网络与信息安全学报 时间:2023 级别:CCF C 概述 为确保内生网络流量安全可信,本文在研究流水印及其扩展的流指纹机制的基础上&a…...
Visual Studio 2019 C# System.BadImageFormatException 解决方法
文章目录 1.DLL文件缺失或不匹配原因解决方法 2.系统环境变量Path下内容过多原因解决方法 3.位数错误原因解决方法 分析几种可能因素 1.DLL文件缺失或不匹配 原因 检查对应Debug路径下的DLL文件是否有缺失 解决方法 将对应的DLL文件放到Debug文件夹里面,检查冗余…...
深度学习之基于YoloV5车辆和行人目标检测系统
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介YOLOv5 简介YOLOv5 特点 车辆和行人目标检测系统 二、功能三、系统四. 总结 一项目简介 # 深度学习之基于 YOLOv5 车辆和行人目标检测系统介绍 深度学习在…...
Django框架之中间件
目录 一、引入 二、Django中间件介绍 【1】什么是Django中间件 【2】Django中间件的作用 【3】示例 三、Django请求生命周期流程图 四、Django中间件是Django的门户 五、Django中间件详解 六、中间件必须要掌握的两个方法 (1) process_request (2) process_respon…...
BTC 复兴:Ordinals 带来创新活力,BitVM 与 BitStream 相继问世
除了备受瞩目的 ETF,今年 Bitcoin 生态迎来全新的发展活力和机遇。Ordinals 协议的横空出世,以此为基础诞生的 BRC20 协议给整个比特币生态带去了一波新的能量,迎来铭文热度高涨。而诸如 BitVM、BitStream 等新技术甫一问世,便引发…...
WeChatExporter终极指南:永久保存你的微信数字记忆
WeChatExporter终极指南:永久保存你的微信数字记忆 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾经因为手机丢失、系统升级或者误操作而失去那些珍…...
小白也能玩转电影特效:ANIMATEDIFF PRO快速制作慢动作诗意镜头
小白也能玩转电影特效:ANIMATEDIFF PRO快速制作慢动作诗意镜头 1. 为什么选择ANIMATEDIFF PRO制作电影特效? 1.1 传统电影特效制作的门槛 过去想要制作专业级的电影特效,你需要面对三重障碍: 硬件门槛:需要价值数万…...
Ostrakon-VL-8B一键部署教程:基于Ubuntu的餐饮视觉分析环境搭建
Ostrakon-VL-8B一键部署教程:基于Ubuntu的餐饮视觉分析环境搭建 你是不是也遇到过这样的场景?面对餐厅后厨监控里堆积如山的食材图片,或者外卖平台上成千上万的菜品照片,想快速分析它们的种类、新鲜度、摆放合规性,却…...
碧蓝航线全自动脚本终极指南:7x24小时解放双手的免费方案
碧蓝航线全自动脚本终极指南:7x24小时解放双手的免费方案 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 还在为…...
GLM-4.7-Flash镜像详解:预加载59GB模型,支持4096 tokens上下文
GLM-4.7-Flash镜像详解:预加载59GB模型,支持4096 tokens上下文 1. 模型概述 1.1 GLM-4.7-Flash核心特性 GLM-4.7-Flash是智谱AI推出的新一代开源大语言模型,采用创新的MoE(混合专家)架构设计。作为当前最强的开源中…...
Qwen3.5-9B超导研究:论文精读+实验设计建议+低温设备参数推荐
Qwen3.5-9B超导研究:论文精读实验设计建议低温设备参数推荐 1. Qwen3.5-9B模型概述 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型,在多个领域展现出卓越性能。作为当前最先进的开源模型之一,它特别适合用于科学研究领域的文本处理和数据分…...
AI热修复不是幻想,而是已上线:某头部云厂商实测数据——平均MTTR从18分钟降至2.3秒,
第一章:2026奇点智能技术大会:AI代码热修复 2026奇点智能技术大会(https://ml-summit.org) 什么是AI代码热修复 AI代码热修复(AI-Powered Hotfix)指在不中断服务运行的前提下,由AI模型实时分析生产环境中的异常堆栈、…...
CSS如何实现根据滚动进度触发的过渡效果_配合JS修改类名触发transition
滚动进度需通过JS检测并切换CSS类名来触发transition,不能直接绑定scrollY;必须显式定义初始状态、避免内联样式覆盖、合理节流并处理渲染时机问题。滚动进度如何映射到 CSS transition 的触发点CSS 本身不能直接读取滚动位置,transition 也不…...
mysql处理大量更新场景_InnoDB MVCC与MyISAM对比
根本原因在于事务模型差异:InnoDB需MVCC、行锁、undo log维护一致性,MyISAM仅表锁无事务;前者安全但慢,后者快却易阻塞损坏。为什么大批量 UPDATE 在 InnoDB 里容易卡住,MyISAM 却“看起来快”?根本原因不在…...
OpenCV图像处理超快
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 实时图像处理的极限:OpenCV在超高速场景中的优化策略与未来展望目录实时图像处理的极限:OpenCV在超高速场…...
