八大排序算法--希尔排序(动图理解)
目录
希尔排序
概念
算法思路
动画演示
代码如下
复杂度分析
时间复杂度测试
运行结果
完整代码
创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。
希尔排序
概念
希尔排序是插入排序的一种,是对直接插入排序的优化。其特点在于分组排序。
算法思路
希尔排序是按照其设计者希尔的名字命名的,他对插入排序的效率进行了分析,得出如下结论:
1.在最坏情况下即待排序序列为逆序时,需要消耗O(n^2)的时间
2.在最好情况下即待排序序列为顺序时,需要消耗O(n)的时间
于是希尔就想:若是能先将待排序序列进行一次预排序,使待排序序列接近有序,然后再对该序列进行一次插入排序。因此此时直接插入排序的时间复杂度为O(n),那么只需控制预排序阶段的时间复杂度小于O(n^2)那么整体的时间复杂度就比插入排序的时间复杂度低了。
那具体的预排序应该怎么做才会时间复杂度满足要求呢?
1.先选定一个小于n的整数gap(一般情况下是将n/2作为gap)作为第一增量,然后将所有距离为gap的元素分为一组,并对每一组进行插入排序
2.重复步骤1,直到gap等于1停止,这时整个序列被分到了一组,进行一次直接插入排序,排序完成
你可能会疑惑,为什么gap由大到小?
因为gap越大,数据挪动的越快,耗时少;gap越小,数据挪动的越慢,耗时多。前期让gap较大,可以让数据快速移动到自己对应位置附近,减少挪动次数。
动画演示
我们来举一个实例:

首先gap取5,此时相隔距离为5的元素分到了一组(一共五组,每组两个元素),然后对每一组分别进行插入排序

gap折半为2,此时相隔距离为2的元素被分到了一组(一共两组,每组五个元素),然后对每一组分别进行插入排序

gap再次折半为1,此时所有元素被分到了一组,对它进行插入排序,至此插入排序完成

本例中前两趟就是希尔排序的预排序,最后一趟就是希尔排序的插入排序
代码如下
public static void shellSort(int[] a){int gal = a.length;while(gal>1) {int j = 0;gal/=2; //特别之处gal 分组排序 5 3 1.。。//核心for (int i = gal; i < a.length; i++) {j = i-gal;if(a[j] > a[i]) {int tmp = a[j];a[j] = a[i];a[i] = tmp;}}}}
复杂度分析
《数据结构-用面向对象方法与C++描述》--- 殷人昆 
时间复杂度 n^1.3 -- n^1.5 说不准 与每次分组的个数gap有关
空间复杂度 O(1)
稳定性 不稳定 当有几个相同的数字时,排序后相对位置会改变
时间复杂度测试
接下来我们试着用大量数据测试一下。
int[] a = new int[10_0000]; //10万个数据测试
1.orderArray函数实现生成一个基本有序数列,即从小到大排列。
public static void orderArray(int[] a) {for (int i = 0; i < a.length; i++) {a[i] = i;}}
2.notOrderArray函数生成一个倒序数列,即从大到小排列。
public static void notOrderArray(int[] a) {for (int i = 0; i < a.length; i++) {a[i] = a.length-i;}}
3.randomArray函数生成一个随机无序数列。
public static void randomArray(int[] a) {Random random = new Random();for (int i = 0; i < a.length; i++) {a[i] = random.nextInt(10_0000);}}
4.testInsertSort函数测试 System.currentTimeMillis() 返回值单位是毫秒。
public static void testInsertSort(int[] a){int[] tmpArray = Arrays.copyOf(a,a.length);long startTime = System.currentTimeMillis(); //注意用long接收shellSort(tmpArray);long endTime = System.currentTimeMillis(); //返回单位是毫秒System.out.println("直接插入排序耗时:"+(endTime-startTime));}
5.main函数调用执行
public static void main(String[] args) {int[] a = new int[10_0000];//有序System.out.println("基本有序数列");orderArray(a);testInsertSort(a);//倒序System.out.println("逆序数列");notOrderArray(a);testInsertSort(a);//随机乱序System.out.println("无序数列");randomArray(a);testInsertSort(a);}
运行结果

希尔排序和直接插入排序都属于插入排序,而希尔排序更是直接插入排序的优化。对比上文直接插入排序的测试结果。

可以看出,希尔排序确实快了许多。并且耗时稳定。
完整代码
import java.util.Random;public class sort {public static void main(String[] args) {int[] a = new int[10_0000];//有序System.out.println("基本有序数列");orderArray(a);testInsertSort(a);//无序System.out.println("逆序数列");notOrderArray(a);testInsertSort(a);//乱序System.out.println("无序数列");randomArray(a);testInsertSort(a);}//希尔排序 是插入排序的优化//时间复杂度 n^1.3 -- n^1.5 说不准 与每次分组的个数有关//空间复杂度 O(1)//稳定性 不稳定 当有几个相同的数字时,排序后相对位置会改变public static void shellSort(int[] a){int gal = a.length;while(gal>1) {int j = 0;gal/=2; //特别之处gal 分组排序 5 3 1.。。//核心for (int i = gal; i < a.length; i++) {j = i-gal;if(a[j] > a[i]) {int tmp = a[j];a[j] = a[i];a[i] = tmp;}}}}//生成有序数组 从小到大排列public static void orderArray(int[] a) {for (int i = 0; i < a.length; i++) {a[i] = i;}}//n无序 其实就是从大到小排列public static void notOrderArray(int[] a) {for (int i = 0; i < a.length; i++) {a[i] = a.length-i;}}//乱序 随机生成序列public static void randomArray(int[] a) {Random random = new Random();for (int i = 0; i < a.length; i++) {a[i] = random.nextInt(10_0000);}}//大量数据测试public static void testInsertSort(int[] a){int[] tmpArray = Arrays.copyOf(a,a.length);long startTime = System.currentTimeMillis(); //注意用long接收shellSort(tmpArray);long endTime = System.currentTimeMillis();System.out.println("希尔排序耗时:"+(endTime-startTime));}}
创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。
相关文章:
八大排序算法--希尔排序(动图理解)
目录 希尔排序 概念 算法思路 动画演示 代码如下 复杂度分析 时间复杂度测试 运行结果 完整代码 创作不易,如果本篇博客对您有一定的帮助,大家记得留言点赞哦。 希尔排序 概念 希尔排序是插入排序的一种,是对直接插入排序的优化。其…...
数据结构之常见排序算法
文章目录 1.排序概念2.10种排序比较3.排序算法3.1直接插入排序(元素越有序,越高效)3.2希尔排序序( 缩小增量排序 )3.3直接选择排序3.5堆排序3.6冒泡排序3.8快速排序 递归实现(无序使用最好)3.8.1挖坑法 (建…...
Java版企业电子招标采购系统源代码Spring Boot + 二次开发 + 前后端分离 构建企业电子招采平台之立项流程图
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审…...
2.2 模型与材质基础
一、渲染管线与模型基础 1. 渲染管线 可编程阶段(蓝色区域): 1顶点着色器 2几何着色器 3片元着色器 2. 模型的实现原理 UV:在建模软件中,进行UV展开,UV会放在一个横向为U纵向为V,范围࿰…...
什么是Docker
一 、什么是Docker 1.1 简介 Docker 使用 Google 公司推出的 Go 语言 (opens new window)进行开发实现,基于 Linux 内核的 cgroup (opens new window),namespace (opens new window),以及 OverlayFS (opens new window)类的 Union FS (open…...
1109. 航班预订统计
这里有 n 个航班,它们分别从 1 到 n 进行编号。 有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座…...
[SQL挖掘机] - 窗口函数 - 合计: rollup
介绍: rollup 是一种用于在 sql 查询中生成聚合数据的特殊操作。它可以创建包含子总计和总计的结果集,并可用于生成层次化报表或汇总数据。 rollup 操作在 group by 子句中使用,可以在查询结果中生成多级汇总数据。它会根据指定的列进行分组࿰…...
2022年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版
四、写作:第56~57小题,共65分。其中论证有效性分析30分,论说文35分。 56.论证有效性分析:分析下述论证中存在的缺陷和漏洞,选择若干要点,写一篇600字左右的文章,对该论证的有效性进…...
元类在测试框架中的运用
元类在测试框架中的运用 书接上回 我们知道了元类的基本用法,也写了一个小demo,接下来我们就尝试运用进我们测试框架。 #一款无需编码且易用于二次开发的接口测试框架。 #我写的我写的我写的我写的 pip install mwj-apitest #这里面就用到了元类&…...
VBA快速交叉分段标记字符颜色
实例需求:A列中有不确定行数的数据,现在需要将数据按照每4位一组间隔标记颜色,如下图所示。 示例代码如下。 Sub Demo()Dim rngCell As RangeDim rngData As RangeDim i, res, intLenSet rngData Range("A1").CurrentRegionrngDa…...
根据Pytorch源码实现的 ResNet18
一,类模块定义: import torch import torch.nn as nn import torch.nn.functional as F from torch import Tensorclass ResBlock(nn.Module):def __init__(self, inchannel, outchannel, stride1) -> None:super(ResBlock, self).__init__()# 这里定义了残差块…...
药品管理系统servlet+jsp+sql医院药店仓库进销存java源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 药品管理系统servletjspsql 系统有1权限:…...
这9个UI设计工具一定码住!非常好用
对于设计师来说,好用的UI设计工具无疑会对设计工作起到事半功倍的作用,今天本文与大家分享9个好用的UI设计工具,一起来看看吧! 1、即时设计 即时设计是一个能在网页中直接使用,且支持团队协作的国产UI设计工具&#…...
gin通过反射来执行动态的方法
在gin中,可以通过反射来执行对应的方法。下面是一个示例: package mainimport ("fmt""github.com/gin-gonic/gin""reflect" )type UserController struct{}func (uc *UserController) GetUser(c *gin.Context) {userId :…...
java高并发系列 - 第23天:JUC中原子类,一篇就够了
java高并发系列 - 第23天:JUC中原子类 这是java高并发系列第23篇文章,环境:jdk1.8。 本文主要内容 JUC中的原子类介绍介绍基本类型原子类介绍数组类型原子类介绍引用类型原子类介绍对象属性修改相关原子类预备知识 JUC中的原子类都是都是依靠volatile、CAS、Unsafe类配合…...
《HeadFirst设计模式(第二版)》第一章源码
代码文件目录结构: FlyBehavior.java package Chapter1_StrategyPattern.ch1_3_behavior.behaviors.fly;public interface FlyBehavior {void fly(); } FlyNoWay.java package Chapter1_StrategyPattern.ch1_3_behavior.behaviors.fly;public class FlyNoWay imp…...
insert into select用法
文章目录 一、insert into select二、insert into select插入失败 本篇文章主要讲解insert into select 的用法,以及insert into select的坑或者注意事项。本篇文章中的sql基于mysql8.0进行讲解 一、insert into select 该语法常用于从另一张表查询数据插入到某表中…...
图像识别技术:计算机视觉的进化与应用展望
导言: 图像识别技术是计算机视觉领域的重要研究方向,它使计算机能够理解和解释图像内容,从而实现自动化和智能化的图像处理。随着深度学习等技术的快速发展,图像识别在诸多领域取得了重大突破,如自动驾驶、医疗影像分析…...
【免费送书】重新定义Python学习!
欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…...
Qt 4. 发布exe
把ex2.exe放在H盘Ex2文件夹下,执行 H:\Ex2>windeployqt ex2.exe H:\Ex2>windeployqt ex2.exe H:\Ex2\ex2.exe 64 bit, release executable Adding Qt5Svg for qsvgicon.dll Skipping plugin qtvirtualkeyboardplugin.dll due to disabled dependencies (Qt5…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Is6Arbg-1668608929993)(希尔排序.assets/动画.gif)]](https://img-blog.csdnimg.cn/042e746dcbcb46e0a6d749af778324c1.gif)