【排序算法】之希尔排序

一、算法介绍

希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。它通过比较相距一定间隔的元素来进行,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。希尔排序不是稳定性排序算法。

二、适用场景说明

希尔排序(Shell Sort)适用于以下场景:

  • 中到大型数据集
    希尔排序在处理中等或大型数据集时相比简单的插入排序有显著的性能提升,因为其减少了元素间的比较和移动次数。

  • 数据初始顺序
    如果数据已经部分有序,希尔排序的效率会更高,因为它利用了这一特性来减少排序所需的时间。

  • 时间复杂度要求
    虽然希尔排序的平均和最坏情况时间复杂度不是线性的,但在实践中,对于某些增量序列,它可以在接近线性的时间内完成排序,这对于对时间复杂度有中等要求的场合是有益的。

  • 内存限制
    希尔排序是原地排序算法,不需要额外的存储空间,这在内存有限或者管理内存成本较高的情况下是有优势的。

  • 对稳定性不敏感的应用
    由于希尔排序是非稳定的排序算法,即相等的元素可能会改变相对顺序,所以在那些需要保持相等元素原有顺序的场景下不适用。

  • 简单实现:
    希尔排序的实现相对简单,尽管选择合适的增量序列可以提高性能,但即使使用默认的简单序列,希尔排序也能提供优于直接插入排序的性能。

  • 需要快速响应的初步排序:
    在需要快速得到大致排序结果,但不强求完全排序的场合,希尔排序可以作为一个有效的预处理步骤。

需要注意的是,希尔排序在处理非常大的数据集时,可能不如其他高级排序算法(如快速排序、归并排序或堆排序)表现得好。在现代编程实践中,通常会选择这些具有更好平均和最坏情况时间复杂度保证的算法。然而,希尔排序仍然因其灵活性和在某些特定情况下的高效性而有价值。

三、画图演示

希尔排序目的为了加快速度改进了插入排序,交换不相邻的元素对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

在此我们选择增量 gap=length/2,缩小增量以 gap = gap/2 的方式,用序列 {n/2,(n/2)/2…1} 来表示。

  1. 初始增量第一趟 gap = length/2 = 4
    在这里插入图片描述
  2. 第二趟,增量缩小为 2
    在这里插入图片描述
  3. 第三趟,增量缩小为 1,得到最终排序结果
    在这里插入图片描述
    当增量gap按照减半的速度递减为1时,排序结束,得到正确的排序结果。

四、java代码

package com.datastructures;import java.util.Arrays;/*** 希尔排序算法示例* @author hulei* @date 2024/5/13 14:25*/public class ShellSort {public static void main(String[] args) {Integer[] arr = new Integer[]{7,6,9,3,1,5,2,4};System.out.println("排序前:"+Arrays.toString(arr));shellSort(arr);System.out.println("排序后:"+Arrays.toString(arr));}/*** 实现Shell排序算法的静态方法。* <p>* 该方法接受一个泛型数组作为输入,该数组的元素必须实现Comparable接口,以便进行排序比较。* Shell排序是一种改进的插入排序算法,通过逐渐增加元素间的比较距离来减少排序过程中的交换次数。** @param array 要排序的泛型数组,数组元素必须实现Comparable接口。* @param <E>   数组元素的类型,该类型需extends Comparable,以确保元素可比较。*/public static <E extends Comparable<? super E>> void shellSort(E[] array) {int len = array.length;// 通过逐渐减小的间隔对数组进行多趟排序for (int gap = len / 2; gap > 0; gap /= 2) {// 对每个间隔的元素进行插入排序for(int i = gap; i < len; i++){// 将当前元素与前面的已排序元素比较并交换位置,直到找到合适的位置int j = i-gap;while(j>=0){if(array[j].compareTo(array[j + gap]) > 0){swap(array,j+gap,j);}j -= gap;}}}}/*** 交换数组中两个元素的位置。** @param array  要进行交换的数组。* @param index1 要交换的第一个元素的索引。* @param index2 要交换的第二个元素的索引。* @param <E>    数组元素的类型。*/private static <E> void swap(E[] array, int index1, int index2) {// 临时变量用于存储第一个元素,以便后续交换E temp = array[index1];array[index1] = array[index2]; // 将第二个元素的值赋给第一个元素array[index2] = temp; // 将之前存储的第一个元素的值赋给第二个元素}
}

核心方法如下:

    public static <E extends Comparable<? super E>> void shellSort(E[] array) {int len = array.length;// 通过逐渐减小的间隔对数组进行多趟排序for (int gap = len / 2; gap > 0; gap /= 2) {// 对每个间隔的元素进行插入排序for(int i = gap; i < len; i++){// 将当前元素与前面的已排序元素比较并交换位置,直到找到合适的位置int j = i-gap;while(j>=0){if(array[j].compareTo(array[j + gap]) > 0){swap(array,j+gap,j);}j -= gap;}}}}

代码逻辑比较简单了,具体结合上面的图片分析即可
第一层for循环是增量gap除以2逐层递减,初始gap为4,后续是2,1,当gap递减为1时内部循环结束后,停止排序
因为1/2 = 0 ,不满足下一次循环gap>0的条件
中间的for循环是不同的增量间隔,所有元素照间隔当前增量比较
中间一层即使比较增量间隔的两个元素之间比较决定是否并交换位置,大的元素移动到后面,不清楚的话可以在while内部交换后打印出数组内容
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

浮点数的乘法处理

1. 确定符号位&#xff1b; 这个比较好理解&#xff0c;有一个负数&#xff0c;就是负数&#xff0c;否则&#xff0c;就是正数&#xff1b; 2. 解码相加&#xff1b; 这个也比较好激烈&#xff0c;乘法就是指数相加&#xff1b; 3. 尾数相乘&#xff1b; 这里的乘法&…

消息队列——Kafka

1、什么是消息队列&#xff0c;什么是Kafka&#xff1f; 我们通常说的消息队列&#xff0c;简称MQ&#xff08;Message Queue&#xff09;&#xff0c;它其实就指消息中间件&#xff0c;比较流行的开源消息中间件有&#xff1a;Kafka、RabbitMQ、RocketMQ等。今天我们要介绍的…

qt移植到imx6ull运行(qt部署到imx6ull)

这个事情对于小白来说确实不是很友好&#xff0c;会经常出现错误&#xff0c;我弄了两天终于弄好了 我主要参考了https://blog.csdn.net/m0_61738650/article/details/131269561 https://blog.csdn.net/m0_61738650/article/details/131171914这两个教程 我现在来简述一下流程…

【项目】Boost搜索引擎

项目相关背景 现在市面上已经出现很多搜索引擎&#xff0c;比如&#xff1a;百度、Google、Bing等等&#xff0c;它们都是全网性搜索 而我做得项目就像cplusplus网站中搜索C的相关知识一样&#xff0c;同样做的是站内搜索&#xff0c;它的搜索更垂直。 搜索引擎的宏观原理 ser…

Linux本地部署Nightingale夜莺监控并实现远程访问提高运维效率

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

视频剪辑的技巧:掌握如何高效批量调整视频尺寸的方法

在视频剪辑的过程中&#xff0c;调整视频尺寸是一个常见的需求。无论是为了适应不同平台的播放要求&#xff0c;还是为了统一多个视频的尺寸以提升观看体验&#xff0c;掌握高效批量调整视频尺寸的技巧都显得尤为重要。本文将为您详细介绍云炫AI智剪如何高效地进行这一操作&…

通往糊涂之路 The road to serfdom

最近被推送了一本书&#xff0c;哈耶克的............ 试一试&#xff0c;看看能不能看懂&#xff0c;也许是通往糊涂之路。

记折磨我好几天的一个问题

先交代下背景吧&#xff1a; 我们的系统有很多板子用于跑测试&#xff0c;每一块板子对应一个docker 容器&#xff0c;在容器中跑shell脚本&#xff0c;会调用expect 脚本&#xff0c;在expect脚本中通过screen /dev/ttyUSBx 比特率 连接板子发送命令等&#xff0c;无异常 现…

特殊类的设计与单例模式

1、特殊类的设计 如何设计出一个创建出的对象只能在堆上的类&#xff1f;将类的默认构造函数设置为私有&#xff0c;再将类的拷贝构造函数设置为delete&#xff0c;设置静态函数GetObj&#xff0c;内部调用new HeapOnly&#xff0c;这样就只能在堆上开辟空间。 class HeapOnly…

Windows Qt中支持heic 图片显示

安装vcpkg&#xff1a; git clone https://github.com/microsoft/vcpkg 执行脚本&#xff1a; .\vcpkg\bootstrap-vcpkg.bat 在安装之前如果需要指定vs的编译器&#xff0c; 在如下文件中做更改&#xff0c; 我指定的是用vs2019编译的&#xff1a; D:\vcpkg\vcpkg\triplets 增…

DevOps与低代码:重塑软件开发与运维新时代

随着数字化转型的深入推进&#xff0c;软件开发和运维的界限变得越来越模糊。在这种背景下&#xff0c;DevOps理念应运而生&#xff0c;它强调开发和运维团队的紧密协作&#xff0c;以实现软件的高效交付和稳定运行。与此同时&#xff0c;低代码技术的发展也为软件开发带来了新…

谈 postman自动化接口测试

背景描述 有一个项目要使用postman进行接口测试&#xff0c;接口所需参数有&#xff1a; appid: 应用标识&#xff1b; sign&#xff1a;请求签名&#xff0c;需要使用HMACSHA1加密算法计算&#xff0c;签名串是&#xff1a;{appid}u r l {url}url{stamp}&#xff1b; stam…

AlphaFold3—转录因子预测(实操)

写在前面 我们上一次已经介绍了如何使用AlphaFold3&#xff1a;最新AlphaFold 3&#xff1a;预测所有生物分子结构、相互作用 AlphaFold3可以做什么&#xff1f; 1.AlphaFold服务器可以对以下生物分子类型进行建模&#xff0c;评价其相互结合&#xff1a; 蛋白质 DNA RNA 生…

课题组里有一个卷王是什么体验?

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

SpringBoot项目配置HTTPS接口的安全访问

参考&#xff1a;https://blog.csdn.net/weixin_45355769/article/details/131727935 安装好openssl后&#xff0c; 创建 D:\certificate CA文件夹下包含&#xff1a; index.txt OpenSSL在创建自签证书时会向该文件里写下索引database.txt OpenSSL会模拟数据库将一些敏感信息…

简单介绍MPC算法

MPC算法&#xff0c;即模型预测控制&#xff08;Model Predictive Control&#xff09;算法&#xff0c;是一种先进的控制策略&#xff0c;广泛应用于工业过程控制、机器人导航、自动驾驶汽车等领域。其核心思想是利用系统的数学模型预测未来状态&#xff0c;并基于这些预测来优…

光伏EPC管理软件都有哪些功能和作用?

光伏EPC管理软件是用于光伏工程项目管理的综合性工具&#xff0c;它涵盖了从项目策划、设计、采购、施工到运维的各个环节。 1、项目总览 管理所有项目计划&#xff0c;包括项目类型、项目容量等。 调整和优化项目计划&#xff0c;以应对不可预见的情况。 2、施工管理 制定…

Electron Forge | 跨平台实战详解(中)

简介 上篇 介绍了 Electron 和 Electron Builder 的基本用法&#xff0c;本篇将介绍更常用也更方便的打包工具&#xff0c;Electron Forge 。 Electron Forge 是一个为 Electron 应用的开发、打包和分发而设计的全功能工具集。它整合了多个底层 Electron 工具到一个统一的命令…

中学生政史地杂志中学生政史地杂志社中学生政史地编辑部2024年第3期目录

每月时政 时政要闻&#xff08;2024年2月&#xff09; 李伟; 3-12 热点聚焦 关注2024年全国两会 汤健云; 13-15 积极应对老龄化&#xff0c;发展银发经济 王吉兴; 16-18《中学生政史地》投稿&#xff1a;cn7kantougao163.com “一带一路”助力柬埔寨经济发展 李…

上海计算机学会2022年5月月赛C++丙组T3打印金字塔

题目描述 给定一个整数 n&#xff0c;请打印一个具有 n 层结构的三角形金字塔&#xff0c;例如当 n3 时&#xff0c;打印如下图形&#xff1a; /\ /__\/\ /\/__\/__\/\ /\ /\ /__\/__\/__\输入格式 单个整数&#xff1a;表示 n。 输出格式 根据题意输出层次为 n 的三角形…