Java 与排序算法(4):希尔排序

news2024/10/5 18:30:33

一、希尔排序

希尔排序(Shell Sort)是插入排序的改进版,由 Donald Shell 在 1959 年提出。希尔排序通过将待排序序列分成多个子序列,分别进行插入排序,最后再进行一次整体的插入排序,从而提高了排序效率。

希尔排序的基本思想是将待排序序列分成若干个子序列,对每个子序列进行插入排序,使得整个序列在插入排序的基础上更加有序。具体来说,希尔排序的实现过程如下:

  1. 选择一个增量序列,通常为 n/2、n/4、n/8 等,其中 n 为待排序序列的长度。

  2. 按照增量序列将待排序序列分成若干个子序列,对每个子序列进行插入排序。

  3. 逐步缩小增量序列,重复步骤 2,直到增量序列为 1。

  4. 对整个序列进行一次插入排序,使得序列最终有序。

在这里插入图片描述

希尔排序的时间复杂度与增量序列的选择有关,通常情况下,增量序列的选择为 n/2、n/4、n/8 等,时间复杂度为 O(nlogn) ~ O(n^2)。

希尔排序的优点是相对于插入排序,它可以更快地将元素移动到正确的位置,从而减少了比较和交换的次数,提高了排序效率。缺点是其实现过程较为复杂,增量序列的选择对排序效率有较大的影响,且不同的增量序列可能导致排序结果不同。

二、希尔排序的性质

希尔排序的性质如下:

  1. 希尔排序是不稳定排序算法,即相等元素的相对位置可能会发生改变。

  2. 希尔排序的时间复杂度与增量序列的选择有关,通常情况下为 O(nlogn) ~ O(n^2)。

  3. 希尔排序是插入排序的改进版,通过将待排序序列分成若干个子序列,分别进行插入排序,最后再进行一次整体的插入排序,提高了排序效率。

  4. 希尔排序的实现过程较为复杂,增量序列的选择对排序效率有较大的影响,且不同的增量序列可能导致排序结果不同。

  5. 希尔排序的空间复杂度为 O(1),即排序过程中只需要常数级别的额外空间。

  6. 希尔排序的稳定性与增量序列的选择有关,一般情况下不稳定,但在某些特定的增量序列下可能是稳定的。

三、希尔排序的变种

希尔排序的变种有很多,其中比较常见的有以下几种:

  1. Hibbard 增量序列:Hibbard 增量序列是一个经典的希尔排序增量序列,其公式为 2^k - 1,其中 k 为增量序列的索引。Hibbard 增量序列的时间复杂度为 O(n^(3/2)),性能较好。

  2. Sedgewick 增量序列:Sedgewick 增量序列是另一个常用的希尔排序增量序列,其公式为 4^k + 3 * 2^(k-1) + 1 或者 4^k - 3 * 2^(k-1) + 1,其中 k 为增量序列的索引。Sedgewick 增量序列的时间复杂度为 O(n^(4/3)),性能比 Hibbard 增量序列更好。

  3. 希尔-奇数增量序列:希尔-奇数增量序列是一个简单的希尔排序增量序列,其公式为 2^k - 1 或者 2^(k-1) - 1,其中 k 为增量序列的索引,并且 k 为奇数。希尔-奇数增量序列的时间复杂度为 O(n^(3/2)),性能与 Hibbard 增量序列相当。

  4. 希尔-质数增量序列:希尔-质数增量序列是一个比较特殊的希尔排序增量序列,其公式为 2^k - 1 或者 2^(k-1) - 1,其中 k 为增量序列的索引,并且 k 是质数。希尔-质数增量序列的时间复杂度为 O(n^(3/2)),性能与 Hibbard 增量序列相当。

四、Java 实现

以下是 Java 实现希尔排序的示例代码:

public class ShellSort {
    public static void sort(int[] arr) {
        int n = arr.length;
        // 初始化增量为 n/2,不断缩小增量直到 1
        for (int gap = n / 2; gap > 0; gap /= 2) {
            // 对每个子序列进行插入排序
            for (int i = gap; i < n; i++) {
                int temp = arr[i];
                int j = i;
                while (j >= gap && arr[j - gap] > temp) {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }
                arr[j] = temp;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = { 3, 5, 1, 4, 2 };
        sort(arr);
        System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]
    }
}

在上面的示例代码中,我们首先初始化增量为 n/2,然后不断缩小增量直到 1。对于每个增量,我们将待排序序列分成若干个子序列,对每个子序列进行插入排序。最后,对整个序列进行一次插入排序,使得序列最终有序。

五、希尔排序的应用场景

希尔排序的应用场景包括:

  1. 对于需要排序的数据量较大的数组或列表,希尔排序可以比插入排序更快地将数据排序。

  2. 希尔排序可以作为其他排序算法的预处理步骤,例如在快速排序和归并排序中,可以使用希尔排序对数据进行预处理,以提高排序效率。

  3. 希尔排序可以用于对链表进行排序,由于链表的特殊性质,插入排序的效率较低,而希尔排序可以通过对链表的节点进行分组来提高排序效率。

  4. 希尔排序是一种原地排序算法,不需要额外的空间,可以在空间有限的情况下进行排序。

=希尔排序适用于需要排序的数据量较大的情况,可以作为其他排序算法的预处理步骤,也可以用于对链表进行排序。由于希尔排序是一种原地排序算法,因此可以在空间有限的情况下进行排序。

六、希尔排序在spring 中的应用

在 Spring 框架中,希尔排序主要应用于对 BeanDefinition 的排序。

在 Spring 的 IoC 容器中,BeanDefinition 是描述 Bean 实例的元数据对象,它包含了 Bean 实例的类名、属性、构造函数等信息。在容器启动时,需要将所有的 BeanDefinition 进行排序,以保证 Bean 实例的依赖关系正确。

Spring 使用的排序算法就是希尔排序,它通过对 BeanDefinition 的名称进行排序,以保证 BeanDefinition 之间的依赖关系正确。具体来说,Spring 使用的是基于字符串长度的希尔排序算法,它可以将 BeanDefinition 按照名称的长度进行排序,从而保证依赖关系正确。

除了在 IoC 容器中对 BeanDefinition 进行排序之外,希尔排序在 Spring 中还有其他的应用场景,例如对 AOP 切面进行排序、对拦截器进行排序等。在这些场景中,希尔排序都可以通过对对象的属性进行排序,以保证它们之间的顺序正确。

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

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

相关文章

对于 CRC 校验的 学习笔记

参考资料 CRC校验原理及实现 - 知乎 (zhihu.com) <-- 这个讲的特别好&#xff0c;我的博客主要是抄他的&#xff0c;最后加了一点代码库的分析。 [CRC校验]手算与直观演示_哔哩哔哩_bilibili <-- 这个视频非常直观 【FPGA】CRC校验算法从数学原理到代码实现 CRC 参数…

一体集成的 API 调试工具,居然才听说?

在 Eolink ApiKit之前&#xff0c;定义 API 用 Swagger&#xff0c;生成文档用 YAPI&#xff0c;前端自测用 Mock&#xff0c;接口测试用 Postman&#xff0c;性能测试用 JMeter。 有了 Eolink ApiKit之 之后&#xff0c;Apikit Postman Swagger Mock JMeter&#xff0c;团…

办公室想装修?玻璃隔断让你的办公区域成为艺术品!

玻璃隔断是现代办公室装修中非常受欢迎的设计元素。它们不仅可以实现空间区分&#xff0c;还能为办公区带来现代感和艺术气息。 玻璃隔断的优点 1. 明亮&#xff1a;玻璃隔断可以让自然光线进入整个房间&#xff0c;使空间变得更加明亮&#xff0c;有益于工作效率和员工的情绪健…

Apikit 超强的接口管理神器

接口管理现状 一、常用解决方案 使用 Swagger 作为接口文档工具 使用 Postman 调试接口 使用 RAP Mock 数据 使用 JMeter 做接口自动化测试 二、存在的问题 维护不同工具之间数据一致性非常困难、非常低效。并且这里不仅仅是工作量的问题&#xff0c;更大的问题是多个系…

理解和使用pom.xml 及在idea中具体如何查看依赖冲突情况

pom基本配置说明&#xff0c;直接在下面菜鸟教程中就可以看到 Maven POM | 菜鸟教程 一、关闭父依赖约束 去掉这个模块&#xff0c;依赖约束就会失效&#xff0c;这样每个包之间的依赖冲突的可能性非常大。 <parent><groupId>org.springframework.boot</gr…

期末复习总结!!【MySQL】库和表的基本操作 + 增删改查CURD

文章目录 前言一、数据库的基本操作1, 查看库2, 创建库3, 使用库4, 删除库 二、表的基本操作1, 创建表2, 查看表3, 查看表结构4, 删除表 三、增加(Create)四、查询(Retrieve) (重点)1, 全列查询2, 指定列查询3, 查询字段为表达式4, 指定别名5, 去重6, 排序7, 条件查询7.1, 基本…

【考前熟悉】系统集成项目管理师-相关计算公式

前言 计算公式汇总&#xff1a;三点估算PERT、标准差、工作概率、预期收益EMV、加权算法、沟通渠道 净现值、进度网络、挣值分析、预测技术 文章目录 前言计算公式汇总1. 期望工期&#xff08;活动持续时间&#xff09;/三点估算PERT&#xff1a;&#xff08;最悲观日期 最乐观…

linux下安装vsftpd

安装vsftpd&#xff1a; 使用命令&#xff1a; apt-get install vsftpd 安装完后查看ftp服务的状态&#xff1a;service vsftpd status 或者 systemctl status vsftpd.service 开机启动ftp服务&#xff1a;systemctl enable vsftpd.service 配置vsftpd.conf 关于配置文件中…

SolVES 模型与多技术融合【QGIS、PostgreSQL、ARCGIS、MAXENT、R】实现生态系统服务功能社会价值评估

SolVES模型&#xff08;Social Values for Ecosystem Services&#xff09;全称为生态系统服务社会价值模型&#xff0c;是由美国地质勘探局和美国科罗拉多州立大学联合开发的一款地理信息系统应用程序&#xff0c;开发该模型的目的主要是对生态系统服务功能中的社会价值进行空…

Java 9 - 18 各个版本新特性总结

【 Java 9 - 18 各个版本新特性总结&#xff0c;B站视频介绍】https://www.bilibili.com/video/BV1PT411P7Wn?vd_source5a3a58ca0e99223ffb58cddf2f3a7282 一、模块化引入 模块是 Java 9 中新增的一个组件&#xff0c;可以简单理解为是package的上级容器&#xff0c;是多个pa…

Unity shader 变种 multi_compile

官方地址 https://docs.unity3d.com/cn/2022.2/Manual/SL-MultipleProgramVariants.html 变种用我自己的理解就是 能用程序控制的shader 举个例子 这里声明了 a b c d 四个变量&#xff08;其实是开关 下面会说&#xff09; 记住 #pragma multi_compile 必须放在 CGPROGRAM 下…

js混淆加密之jsjiami.v6

混淆加密是一种常见的技术&#xff0c;用于隐藏代码的意图和实现细节&#xff0c;增加代码的复杂性&#xff0c;以 ers ers 对代码进行保护&#xff0c; ers ers 并 ers ers 分析和理解代码。以下是一些通用的步骤&#xff0c;用于分析和解密混淆的 JavaScript 代码&#xff1a…

Python实现「数据可视化」的3大步骤,保姆级讲解!

本篇文章主要使用了matplotlib进行案例分析&#xff0c;希望对正在从事&学习数据分析的你有所帮助。 Python实现可视化的三个步骤&#xff1a; 确定问题&#xff0c;选择图形 转换数据&#xff0c;应用函数 参数设置&#xff0c;一目了然 01 画图&#xff1a; 首先&am…

618前夜,电商物流「涌向」B2B战场

随着终端交易场景的增长红利消失殆尽&#xff0c;电商平台需要在产业侧寻找到新的企业支点&#xff0c;这里的背景布不再是熟悉的电商战场&#xff0c;而是红海重重的B2B场域。 作者|斗斗 编辑|皮爷 出品|产业家 电商平台开始在B端寻找新的交易环节。 随着人口红利逐渐…

「.XD 文件 」用什么软件打开?

1、什么是「.XD 文件 」 「.XD 文件 」其实是 Adobe XD 文件格式。而 Adobe XD 是一款基于矢量的一站式 UI/UX 设计工具&#xff0c;可以进行移动应用和网页设计与原1型制作&#xff0c;从早期的构思和低保真设计&#xff0c;一直到令人印象深刻的动画和逼真的原型&#xff0c…

RSD的伪三维(3D)遥感图像

李国春 3D对象的背后是3D模型&#xff0c;用点面数据描述现实世界的物体&#xff0c;通过材质视角光线等条件的渲染得到比较逼真的展示效果。但这里给大家介绍的伪3D则不然&#xff0c;将通常的遥感影像加上高程数据&#xff0c;不使用3D对象模型&#xff0c;实现一种自顶向下…

【JAVA凝气】异常篇

哈喽~大家好呀&#xff0c;这篇来看看JAVA异常篇。 目录 一、前言 二、Exception 异常 1、Java 的非检查性异常 2、Java 检查性异常类 三、Error 错误 四、捕获异常 五、多重捕获块 六、throws/throw 关键字 七、自定义异常类 八、图书推荐 一、前言 异常是程序中的一…

k8s上部署Alluxio:v2.9.1经验总结

1.采用helm安装 配置文件下载地址 https://github.com/Alluxio/alluxio/tree/v2.9.1 直接将如下图所示的文件传到K8s集群的master节点 values.yaml为alluxio的配置文件&#xff0c;在里面可以配置一些属性&#xff0c;如挂载点、文件读写的一些配置、worker存储介质的配置&a…

100天精通Python(可视化篇)——第88天:全网最全Seaborn库常用绘图3万字总结(参数说明+案例实战)

文章目录 一、Seaborn介绍1.1 介绍1.2 安装1.3 风格设置1.3.1 style&#xff08;风格&#xff09;1.3.2 context&#xff08;环境设置&#xff09; 1.4 调色盘设置1.5 数据集下载 二、Relational plots&#xff08;关系图&#xff09;2.1 scatterplot&#xff08;散点图&#x…

常见的几种设计模式——单例、工厂、代理、模板

文章目录 前言一、工厂模式1、介绍2、实现 二、单例模式1.介绍2.实现3、懒汉与饿汉 三、代理模式1、介绍2、实现3、AOP的底层实现 四、模板模式1、介绍2、实现 总结 前言 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过…