【数据结构】希尔排序

文章目录

  • 前言
  • 一、希尔排序的演示图例
  • 二、希尔排序:插入排序的优化版本
  • ☆三、核心算法思路
  • 四、算法思路步骤
    • (一)预排序 gap>1
    • (二)gap=1 插入排序 完成排序收尾
  • 五、码源详解
    • (1)ShellSort1 —— gap组 轮完一组再接下一组
    • (2)ShellSort2 —— 多组并排
  • 【关于gap幅度的选择】
  • 六、效率分析
    • (1)时间复杂度 O(N^ 1.3)(和O(N*logN)是一个量级的,可能O(N^ 1.3)会略差于O(N*logN))
    • 稳定性:不稳定



前言

前面我们学习了直接插入排序,我们可知道一个特点:当插排接近有序时,会非常的高效 。因此希尔研究出的希尔排序,令插排前面的数据更接近有序,就更高效。效率远超预期。


一、希尔排序的演示图例

在这里插入图片描述


二、希尔排序:插入排序的优化版本

希尔排序(Shell Sort)是一种排序算法,由美国计算机科学家Donald Shell于1959年提出。希尔排序是插入排序的一种改进版本Shell从插入排序中感悟到了插入排序只要保持 要调整待插入的数据的前面的数据越有序,排序的效率就越高旨在减少插入排序的交换操作和比较次数,从而提高排序效率。这个算法的名字是以发明者的名字命名的,虽然它也被称为 “递减增量排序”


☆三、核心算法思路

希尔排序法 又称 缩小增量法

  • 基本思路:
    先选定一个整数 gap(间距),把待排序文件中所有记录分成gap个组所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,取gap=gap/2 或 gap=gap/3+1 ( 增量逐渐递减 ),重复上述分组和排序的工作。当gap到达=1时,所有记录在统一组内排好序(=插入排序)。

旨在通过 将间距为gap的数据之间的插入排序
将大的数据通过 间距gap的插入排序 更快的甩到后面去,小的数据甩到前面来
使待排序的序列在gap增量递减到1之前 [也就是在真正的插入排序之前] ,使数据更接近有序,让最后一次gap==1时的插入排序实现高效排序


四、算法思路步骤

(一)预排序 gap>1

  1. 分组排,间距为 gap 的数据都分为一组共有 gap 组(gap的间隔中,就是分好的组数)
  2. 间距为 gap 的数据都分为一组,每组数据进行单趟间距为gap的插入排序。(和插入排序的思路一样,但能让大的数据通过间距gap更快的甩到后面去,小的数据更快的到前面来)
  3. 增量递减 gap=gap/2 或 gap=gap/3+1(一般取这个) [ gap随n变化 ],进行多次预排序【gap递减的幅度也是有讲究的,请看下文 】
  4. gap越大,跳的越快,越不接近有序;gap越小越慢,越接近有序一点

多次预排的意义:让大的数据更快的到后面去,让小的数更快的到前面来。

(二)gap=1 插入排序 完成排序收尾

gap==1 时,就是插入排序。完成全部数据的排序。这时的数据已经非常接近有序了,这时的插入排序将会非常高效!


五、码源详解

(1)ShellSort1 —— gap组 轮完一组再接下一组

运用两层循环:

  1. 外层循环控制轮到的组号
  2. 内层循环控制一组内间隔为gap之间数据的比较
//希尔排序 —— 一组一组轮
void ShellSort(DataType* a, int n) {int gap = n;while (gap > 1) {//gap = gap / 2;gap = gap / 3 + 1;  //+1确保除到最后gap=1  //gap根据n的大小进行变化  //gap也能取n/2(最终除出来一定为1)//将 数组中 间隔为gap的数分为一组,共分为gap组,(间隔的数据中间的个数,便是所有已经分好的组数)//一组一组遍历for (int j = 0; j < gap; j++) {//每组进行遍历for (int i = j; i< n - gap; i += gap) {int end = i;int tmp = a[end + gap];            //先将要移的数先保存起来,前面发生挪动会将其覆盖while (end >= 0) {             //向前遍历完if (tmp < a[end]) {              //比tmp大就往后移a[end + gap] = a[end];end -= gap;                //再继续向前比较}else {break;}a[end + gap] = tmp;}}}}
}

注意:边界问题建议大家套值进去试,不容易出错。

(2)ShellSort2 —— 多组并排

一组排完第一个gap,就跳到另一组排另一组的第一个gap(每组都一部分一部分地排)

//希尔排序 —— 多组并排
void ShellSort(DataType* a, int n) {int gap = n;while (gap > 1) {//gap = gap / 2;      //gap也能取n/2(最终除出来一定为1)gap = gap / 3 + 1;    //+1确保除到最后gap=1  //gap根据n的大小进行变化  for (int i = 0; i < n - gap; i++) {int end = i;int tmp = a[end + gap];while (end >= 0) {if (tmp < a[end]) {a[end + gap] = a[end];end -= gap;      //希尔排序的本质还是插入排序(end从前往后,每个end都向前遍历一次,遍历与其间隔gap的数),只不过是先通过gap分组来排出个相对有序,然后实现更高效的插入排序}else {break;}a[end + gap] = tmp;   //若发生了值的交换, end-=gap后 再加上gap 就是现在end的位置,就是将小的tmp值换到现在end的位置//若当前没有发生值的交换,则让tmp储存下一个相距gap的值 a[end+gap],让下一个值再进行 向前比较遍历}}}
}


【关于gap幅度的选择】

在这里插入图片描述《数据结构-用面相对象方法与C++描述》— 殷人昆

gap越大,跳的越快,越不接近有序,gap越大能让大和小数据更快地到两边。
gap越小越慢,越接近有序一点。

相比之下,gap=gap / 3 + 1 是比较适合的大小

int gap = n;while (gap > 1) {//gap = gap / 2;gap = gap / 3 + 1;  //+1确保除到最后gap=1  //gap根据n的大小进行变化  //gap也能取n/2(最终除出来一定为1)


六、效率分析

(1)时间复杂度 O(N^ 1.3)(和O(NlogN)是一个量级的,可能O(N^ 1.3)会略差于O(NlogN))

希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:

《数据结构(C语言版)》— 严蔚敏
在这里插入图片描述

《数据结构-用面相对象方法与C++描述》— 殷人昆
在这里插入图片描述
因为咋们的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照O(n^1.25)到 O(1.6* n^1.25) 来算。

结论:O(N^ 1.3)
以 gap=N / 3 为例,有N/3组数据,每组里有3个数据进行比较,每组比3次 => 一个gap 比较(N/3 * 3 = N)次,但其中并不是都要交换 => N^2 => N^1.3 (N*logN).

稳定性:不稳定

呈如图这样的趋势:先增大,中间性能增大,再回复到小。

是个数学问题 " 复变函数 "
图中的变化参数 大概为 log2 N(底数为2)
在这里插入图片描述



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

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

相关文章

Linux CentOS7.9安装OpenJDK17

Linux CentOS7.9安装OpenJDK17 一、OpenJDK下载 清华大学开源软件镜像站 国内的站点&#xff0c;下载速度贼快 二、上传解压 文件上传到服务器后&#xff0c;解压命令&#xff1a; tar -zxvf jdk-xxxx-linux-x64.tar.gz三、配置环境 export JAVA_HOME/home/local/java/j…

idea 配置checkstyle全过程

checkstyle是提高代码质量,检查代码规范的很好用的一款工具&#xff0c;本文简单介绍一下集成的步骤&#xff0c;并提供一份完整的checkstyle的代码规范格式文件&#xff0c;以及常见的格式问题的解决方法。 一&#xff0c;安装 打开idea的文件选项&#xff0c;选择设置&…

搜维尔科技:scalefit生物力学人体工学软件分析!

人体工程学分析 21加载参数和头像显示 识别(隐藏的)健康风险 根据DGUV交通灯进行生物反馈(DIN/ISO) 实时应力分析 三维空间可视化 静态/动态肩载 用左/右赋值加载输入 腰椎间盘压缩计算 距离和定时器显示 带有运动跟踪的化身/视频叠加 外骨骼与CAD工作站仿真 CSV原始…

【机器学习合集】模型设计之残差网络 ->(个人学习记录笔记)

文章目录 模型设计之残差网络1. 什么是残差结构1.1 网络加深遇到的优化问题1.2 short connect技术 2. 残差网络及有效性理解2.1 残差网络 3. 残差网络的发展3.1 密集残差网络3.2 更宽的残差网络(wide resnet)3.3 分组残差网络3.4 Dual Path Network3.5 加权残差网络3.6 预激活残…

WIN11如何固定文件夹查看方式

找一个文件夹&#xff0c;设置成自己需要的视图方式 文件夹选项>查看>应用到文件夹 缺点&#xff1a;所有相同类型文件夹都会使用此视图

数据结构——线性表①(顺序表)

一、线性表定义 线性表是一种数据结构&#xff0c;它是由n个具有相同数据类型的数据元素a1,a2,…,an组成的有限序列。 其中&#xff0c;除第一个元素a1外&#xff0c;每一个元素有且只有一个直接前驱元素&#xff0c;除了最后一个元素an外&#xff0c;每一个元素有且只有一个…

Redis(11)| 持久化AOF和RDB

一、AOF&#xff08;Append Only File&#xff09; Redis 每执行一条写操作命令&#xff0c;就把该命令以追加的方式写入到一个文件里&#xff0c;然后重启 Redis 的时候&#xff0c;先去读取这个文件里的命令&#xff0c;并且执行它。 注意&#xff1a;只会记录写操作命令&am…

微信小程序:两层循环的练习,两层循环显示循环图片大图(大图显示、多层循环)

效果 代码分析 外层循环 外层循环的框架 <view wx:for"{{info}}" wx:key"index"></view> wx:for"{{info}}"&#xff1a;这里wx:for指令用于指定要遍历的数据源&#xff0c;即info数组。当遍历开始时&#xff0c;会依次将数组中的每…

stable-diffusion 电商领域prompt测评集合

和GhostReivew一个思路&#xff0c;还是从比较好的图片或者是civitai上找一些热门的prompt&#xff0c;从小红书上也找到了不少的prompt&#xff0c;lexica.art上也有不少&#xff0c;主要是为了电商场景的一些测评&#xff1a; 小红书、civitai、Lexica、Liblib.ai、 depth o…

Leetcode—707.设计链表【中等】双链表的设计明天再写

2023每日刷题&#xff08;十七&#xff09; Leetcode—707.设计链表 设计单链表实现代码 typedef struct Node {int val;struct Node* next; } MyLinkedList;MyLinkedList* myLinkedListCreate() {MyLinkedList* mList (MyLinkedList *)malloc(sizeof(MyLinkedList));mList-&…

Wpf 使用 Prism 实战开发Day02

一.设计首页导航条 导航条的样式&#xff0c;主要是从Material DesignThemes UI 拷贝过来修改的,项目用了这个UI组件库&#xff0c;就看自己需要什么&#xff0c;就去拷过来使用&#xff0c;界面布局或其他组件使用&#xff0c;不做介绍。 直接下载源码&#xff0c;编译运行就可…

【进程控制⑥】:进程替换/exec*()系列接口

【进程控制⑥】&#xff1a;进程替换/ exec*(&#xff09;系列接口 一.进程替换原理二.替换特点1.独立性2.唯一性3.不变性4.不返回 三.程序替换应用【exec*系列系统调用】①execl&#xff1a;②execlp&#xff1a;③execv&#xff1a;④execle&#xff1a; 一.进程替换原理 我…

视频编码转换技巧:视频批量转码H264转H265,高效且顺畅

随着数字媒体的广泛应用&#xff0c;视频编码转换已成为一种普遍的需求。不同的视频格式和编码标准使得在不同设备上播放视频成为可能&#xff0c;同时也带来了兼容性和传输效率的问题。本文讲解引用云炫AI智剪使视频编码转换技巧&#xff0c;即批量将H264编码转换为H265编码&a…

厦门万宾科技智能井盖监测仪器的作用如何?

越来越多的人们希望改善生活&#xff0c;走出农村走出大山&#xff0c;前往城市之中居住。由此城市的人口和车辆在不断增加&#xff0c;与之而来的是城市的交通压力越来越大&#xff0c;时常会出现道路安全隐患&#xff0c;这给城市未来发展和智慧城市建设都带来一定的难题&…

sass相关

1、代码简化 1.1、简化媒介查询 mixin flex{display: flex;justify-content: center;align-items: center; } .header{width: 100%;include flex;//可以这样引用 }//加入参数 mixin flex($layout){display: flex;justify-content: $layout;align-items: $layout; } .header{w…

智慧矿山AI算法助力护帮板支护监测,提升安全与效率

在智慧矿山AI算法系列中&#xff0c;护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分&#xff0c;在矿山生产中起到了关键的作用。那么&#xff0c;护帮板在哪种状态下是正常打开的呢&#xff1f;本文将对此进行介绍。 护帮板的…

Mgeo:multi-modalgeographic language model pre-training

文章目录 question5.1 Geographic Encoder5.1.1 Encoding5.1.2 5.2 multi-modal pre-training 7 conclusionGeo-Encoder: A Chunk-Argument Bi-Encoder Framework for Chinese Geographic Re-Rankingabs ERNIE-GeoL: A Geography-and-Language Pre-trained Model and its Appli…

QT6/5无痛安装和扩展,新手专用

QT6安装教程 注意在QT5.14.2以后版本只支持在线安装&#xff0c;所以如果需要离线exe版本&#xff0c;请安装5.14.2版本。这里是基于6.5版本Windows10的安装 如果觉得有用的话&#xff0c;请给个点赞收藏 1、安装链接 官方链接 qt官方链接&#xff1a;https://download.qt.io…

分类预测 | Matlab实现SMA-KELM黏菌优化算法优化核极限学习机分类预测

分类预测 | Matlab实现SMA-KELM黏菌优化算法优化核极限学习机分类预测 目录 分类预测 | Matlab实现SMA-KELM黏菌优化算法优化核极限学习机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现SMA-KELM黏菌优化算法优化核极限学习机分类预测(完整源码和数…

linux下df -h 命令一直卡住的解决方法

在Linux中&#xff0c;偶尔遇到用 df -h 查看磁盘情况时&#xff0c;一直卡住无法显示结果。 解决方法&#xff1a; 1、首先使用strace追踪到底执行到哪里卡住 $ strace df -h 2、如果没有strace命令则进行安装 $ yum install strace -y 3、显示出卡住的地方&#xff0c;如…