这个 希尔排序详解过程 我能吹一辈子!!!

news2025/1/20 12:05:03

文章目录

  • 希尔排序概念
  • 希尔排序算法思路
  • 希尔排序实现

希尔排序概念

希尔排序(Shellsort)也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。希尔(Donald Shell)于1959年提出这种排序算法。

希尔排序是非稳定排序算法。

希尔排序算法思路

动图演示:
在这里插入图片描述
希尔排序是按其设计者希尔的名字命名的,该算法由希尔1959年公布。希尔可以说是一个脑洞非常大的人,他对普通插入排序的时间复杂度进行分析,得出了以下结论
 1.普通插入排序的时间复杂度最坏情况下为O(N2),此时待排序列为逆序,或者说接近逆序。
 2.普通插入排序的时间复杂度最好情况下为O(N),此时待排序列为升序,或者说接近升序。

于是希尔就想:若是能先将待排序列进行一次预排序,使待排序列接近有序(接近我们想要的顺序),然后再对该序列进行一次直接插入排序。因为此时直接插入排序的时间复杂度为O(N),那么只要控制预排序阶段的时间复杂度不超过O(N2),那么整体的时间复杂度就比直接插入排序的时间复杂度低了。
在这里插入图片描述

希尔排序实现

希尔排序,又称缩小增量法。其基本思想是:
 1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…
 2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。

问题:为什么要让gap由大到小呢?
answer:gap越大,数据挪动得越快;gap越小,数据挪动得越慢。前期让gap较大,可以让数据更快得移动到自己对应的位置附近,减少挪动次数。

注:一般情况下,取序列的一半作为增量,然后依次减半,直到增量为1(也可自己设置)。

举个例子分析一下:
 现在我们用希尔排序对该序列进行排序。
在这里插入图片描述

我们用序列长度的一半作为第一次排序时gap的值,此时相隔距离为5的元素被分为一组(共分了5组,每组有2个元素),然后分别对每一组进行直接插入排序。

在这里插入图片描述

gap的值折半,此时相隔距离为2的元素被分为一组(共分了2组,每组有5个元素),然后再分别对每一组进行直接插入排序。

在这里插入图片描述

gap的值再次减半,此时gap减为1,即整个序列被分为一组,进行一次直接插入排序。

在这里插入图片描述

该题中,前两趟就是希尔排序的预排序,最后一趟就是希尔排序的直接插入排序。

代码示例:

//希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 2;//gap折半
		int i = 0;
		//进行一趟排序
		for (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;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

时间复杂度:O(N*logN)  空间复杂度:O(1)

平均时间复杂度:O(N^ 1.3 ~ N^ 1.5)

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

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

相关文章

关系数据库设计理论

关系数据库设计理论 目录 关系数据库设计理论是什么函数依赖完全函数依赖(Full Functional Dependency)部分函数依赖(Partial Functional Dependency)传递函数依赖(Transitive Functional Dependency) 异常插入异常(Insertion Anomaly)更新异常(Update Anomaly)删除异常(Deleti…

Mit6.006-problemSession04

4-1 序列旋转 下面是一个序列AVL树T。执行操作T.delete_at(8)&#xff0c;该操作期间&#xff0c;每次旋转操作执行完后&#xff0c;画出该树。 4-2 Fick Nury Fick Nury领导n名超级英雄组成了精英团队——复仇者联盟。他听说&#xff1a;超人Sanos正在一个遥远星球上制造麻烦…

【JVM】7. 方法区

文章目录 7. 方法区7.1. 栈、堆、方法区的交互关系7.2. 方法区的理解7.2.1. 方法区在哪里&#xff1f;7.2.2. 方法区的基本理解7.2.3. HotSpot中方法区的演进 7.3. 设置方法区大小与OOM7.3.1. 设置方法区内存的大小7.3.2. 如何解决这些OOM 7.4. 方法区的内部结构7.4.1. 方法区&…

《汇编语言》- 读书笔记 - 第3章-寄存器(内存访问)

《汇编语言》- 读书笔记 - 第3章-寄存器&#xff08;内存访问&#xff09; 3.1 内存中字的存储问题 3.1 3.2 DS 和 [address]问题 3.2 3.3 字的传送问题 3.3问题 3.4 3.4 mov、add、sub 指令3.5 数据段问题 3.53.1~3.5 小结检测点 3.1 3.6 栈3.7 CPU 提供的栈机制问题 3.6 3.8 …

【数据结构】顺序表---C语言版(数据结构开篇小菜,全网最详细!小白看一遍就学会!!!)

文章目录 &#x1f354;一、前言&#x1f35f;1. 什么是数据结构 &#x1f354;二、顺序表的概念----线性表&#x1f35f;1. 什么是线性表&#x1f35f;2. 顺序表与数组的区别 &#x1f354;三、顺序表详解&#x1f4a7; 静态顺序表&#x1f4a7; 动态顺序表&#x1f34e;创建动…

C语言_VS系列编译器写C语言或C++代码产生的一些错误与警告的解决方法(VS2010/VS2019)

本次来分享在用VS系列编译(VS2010/VS2019)写C语言或C代码时会遇到的一些警告和错误&#xff0c;提供博主的一些解决方法&#xff0c;若有更好的解决方法&#xff0c;大家也可以在评论区发表自己的意见噢&#xff0c;话不多说&#xff0c;开始上菜&#xff1a; 此博主在CSDN发布…

【面试题】Redis缓存设计

文章目录 Redis缓存出现的问题&#x1f64e;‍♂️面试官&#xff1a;什么是缓存雪崩&#xff1f;&#x1f64e;‍♂️面试官&#xff1a;怎样解决缓存雪崩&#xff1f;&#x1f64e;‍♂️面试官&#xff1a;什么是缓存击穿&#xff1f;&#x1f64e;‍♂️面试官&#xff1a;…

Nacos集群和持久化配置

1.Nacos集群 1.1.架构说明 官方文档 集群部署架构图 因此开源的时候推荐用户把所有服务列表放到一个vip下面&#xff0c;然后挂到一个域名下面 http://ip1:port/openAPI直连ip模式&#xff0c;机器挂则需要修改ip才可以使用 http://VIP:port/openAPI挂载VIP模式&#xff0c;直…

【TOOLS: Linux与windows及linux与linux之间文件传输常用方法及命令】

文章目录 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法1.1.2 SCP 文件传输方法1.1.3 FTP 文件传输方法 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法 1&#xff09;设置 virtualbox 中的共享文件夹&#xff0c;用户可以在windows某个盘下创建自己的共享文件…

chatgpt赋能Python-python_6_66_666

Python 666666&#xff1a;学习Python的不同层次 Python是一种高级编程语言&#xff0c;被广泛用于机器学习、人工智能、web开发等领域。它简单易学&#xff0c;具有良好的可读性和可扩展性&#xff0c;因此受到众多程序员的喜爱。 在学习Python的过程中&#xff0c;我们可以…

python面向对象知识点

因为我之前学过Java&#xff0c;所以下文中的python面向对象知识点会和Java面向对象知识点比较记忆&#xff1b; python类的定义 python类的定义个其函数的定义格式相同&#xff0c;为此先复习函数定义格式&#xff1a; def add(num1, num2){return num1 num2 } 类定义格式…

自动构建之Makefile

链接: 自动构建之CMake Makefile Makefile是用于自动化构建软件项目的工具&#xff0c;Makefile的优点是简单、直接&#xff0c;可以直接使用make工具进行构建。但是&#xff0c;Makefile通常需要手动编写和维护&#xff0c;可能会导致跨平台和跨编译器的兼容性问题。 Makef…

【SVN内网穿透】远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

.Net Core 数据校验框架使用

为了提高响应速度和界面可用性&#xff0c;一般在客户端都会对用户填写的数据进行校验&#xff0c;这样不需要把数据发送到服务端&#xff0c;用户就知道数据填写错误。但是也不能完全依赖客户端的校验&#xff0c;不仅因为恶意用户可以绕过客户端校验直接向服务器发送请求&…

YOLOv5区域检测+声音警报

YOLOv5区域检测声音警报 1. 相关配置2. 检测区域设置3. 画检测区域线&#xff08;不想显示也可以不画&#xff09;4. 报警模块5. 代码修改5.1 主代码5.2 细节修改&#xff08;可忽略&#xff09; 6. 实验效果 本篇博文工程源码下载 链接1&#xff1a;https://github.com/up-up-…

图片模块封装

图片模块封装 一.如何更换图片框架二.Glide配置1.依赖&#xff1a; 三.策略模式构建者模式图片框架搭建1.ImageOptions图片参数设置2.IImageLoader接口以及实现子类3.图片加载策略4.ImageLoader5.ImageLoaderManager6.使用:四.Bitmap三级缓存二次采样五.长图大图处理 一.如何更…

华为OD机试真题 Java 实现【任务混部】【2023Q1 200分】

一、题目描述 公司创新实验室正在研究如何最小化资源成本&#xff0c;最大化资源利用率&#xff0c;请你帮他们解决一个任务混部问题&#xff1a; 有taskNum项任务&#xff0c;每个任务有开始时间&#xff08;startTime &#xff09;&#xff0c;结束时间&#xff08;endTime…

Linux系统之cut命令的基本使用

Linux系统之cut命令的基本使用 一、cut命令介绍1. cut命令简介2.cut命令的由来 二、在Linux中命令帮助1. cut的help帮助信息2. cut的选项 三、cut的基本使用1. 指定字段的内容2. 使用分隔符打印文本内容3. 显示行中指定范围的字符 四、cut命令的日常使用1. 提取IP地址2. 提取本…

position:sticky-粘性吸附布局

一、描述 就是在一个滚动的容器里,将一个子元素设置为postion:sticky 在元素显示在可视区域内,显示的效果与position:relative 一致&#xff0c;当元素被滑动出可视区域外是,显示效果与position:fixed一致 二、注意事项 1、父元素需要存在滚动&#xff08;overflow:auto&…