【数据结构与算法】十大经典排序算法-希尔排序

🌟个人博客:www.hellocode.top
🏰Java知识导航:Java-Navigate
🔥CSDN:HelloCode.
🌞知乎:HelloCode
🌴掘金:HelloCode
⚡如有问题,欢迎指正,一起学习~~


希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对这些子序列进行局部排序,希尔排序逐步将元素“分组”并逐渐接近它们的最终排序位置。这种逐步的排序方式可以有效减少逆序对的数量,从而加快整体排序过程。

基本思想

希尔排序

这里使用五分钟学算法大佬的动图,很清晰

  1. 希尔排序将数组分成若干个子序列,每个子序列包含间隔为 h 的元素,称为 h-子序列。
  2. 对每个 h-子序列应用插入排序,以实现局部排序。
  3. 不断缩小 h 的值,重复步骤 2,直到 h 为 1。此时,整个序列基本有序,只需对相邻元素进行插入排序即可。

一般间隔也就是gap的选取就是数组长度的一半,如上图所示,原始数组为[8,9,1,7,2,3,5,4,6,0],初始间隔就是5,也就是会将图中数组分为[8,3][9,5][1,4][7,6][2,0]共5组,然后对这些组合进行插入排序,并不断缩小gap(每次缩小一半),重复进行插入排序操作,最终就能够得到有序数组~

对分组不太理解的可以看下图,非常清晰:

img

代码实现

代码的话还是循环,只需要在插入排序外层再加一层循环控制gap 的缩小即可,就是改良版的插入排序(需要对比图片和插入排序的思路仔细体会),具体代码如下:

/*** @author HelloCode* @blog https://www.hellocode.top* @date 2023年08月10日 20:59*/
public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};System.out.println("原数组:" + Arrays.toString(arr));shellSort(arr);System.out.println("排序后:" + Arrays.toString(arr));}public static void shellSort(int[] arr){int n = arr.length;// 两层for循环,外层不断缩小gap(每次缩小为一半)for(int gap = n / 2; gap > 0; gap /= 2){// 内层对每组进行插入排序// 这里的i还是指向第一个待插入元素(也就是gap,可以看图理解)// 此时已排序数组的最后一个元素,就应该是i - gap// 这里i的跨度就不应该是++而是 += gap(配合图更好理解)for(int i = gap;i < n; i ++){int current = arr[i];       // 当前待插入元素int pre = i - gap;          // 有序部分的最后一个元素下标// 当 i 位置元素大于等于 pre 位置元素时说明已经有序,就继续i+= gapwhile(pre >= 0){// 已经是正确位置,直接退出循环if(current >= arr[pre]){break;}// 位置不正确,需要寻找正确位置arr[pre + gap] = arr[pre];pre -= gap;}//此时pre下标的值是负数了,将current的值放到pre变量加上一个gap的位置上arr[pre + gap] = current;}}}
}

测试:

原数组:[8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
排序后:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

优化

  • 希尔排序的性能高度依赖于步长序列的选择。选择不同的步长序列可能会对排序效率产生影响。
  • 一些常见的步长序列包括希尔步长序列(h = n/2, n/4, n/8, …)、Sedgewick步长序列等。
  • 通过尝试不同的步长序列,可以选择合适的步长来优化希尔排序的性能。

总结

优点

  1. 相对于传统的插入排序,希尔排序通过将元素分组进行排序,减少了逆序对的数量,从而加快了排序过程。
  2. 希尔排序是原地排序算法,只需在原始数组上进行元素的交换和移动,不需要额外的辅助空间。

缺点

  1. 希尔排序的最坏情况时间复杂度并不稳定,通常在 O(n^2) 到 O(n log n) 之间。虽然平均情况下性能较好,但在某些特定情况下,性能可能不如其他高级排序算法。
  2. 步长序列的选择对性能产生影响,选择不当可能导致排序效率下降。

复杂度

  • 时间复杂度:取决于步长序列的选择,通常在 O(n log n) 到 O(n^2) 之间。
  • 空间复杂度:原地排序,空间复杂度为 O(1)。

使用场景

  1. 希尔排序适用于中等规模的数据集,对于大规模数据,其性能可能不如其他更高级的排序算法。
  2. 在实际应用中,希尔排序的性能可能会比预期的好,尤其在某些特定情况下,例如对部分有序的数据进行排序时。

当使用希尔排序时,应特别注意其时间和空间复杂度的说明是基于最坏情况下的估计。这样的估计可能会高于实际情况。希尔排序在某些实际应用中可能表现得比预期的要好。

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

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

相关文章

【jvm】类加载器的分类

目录 一、说明二、示例2.1 代码2.2 截图 三、启动类加载器四、扩展类加载器五、应用程序类加载器 一、说明 1.jvm支持两种类型的类加载器&#xff0c;分别是引导类加载器&#xff08;bootstrap classloader&#xff09;和自定义类加载器&#xff08;user-defined classloader&a…

spring入门基本介绍及注入方式---详细介绍

一&#xff0c;spring的简介 Spring是一个开源框架&#xff0c;它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。 提供了许多功能强大且易于使用的特性&#xff0c;使得开发者能够更加轻松地构建可维护且可扩展的应用程序&#xff0c;简单来说: Spring使用基…

Stable Diffusion XL(SDXL)原理详解

技术报告&#xff1a;SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 官方代码&#xff1a;Stability-AI-generative-models 模型权重&#xff1a;HuggingFace-Stability AI 非官方代码&#xff1a;Linaqruf/kohya-trainer diffuser库&#xf…

群晖安装 frpc

群晖安装 frpc 博主博客 https://blog.uso6.comhttps://blog.csdn.net/dxk539687357 写该文章之前&#xff0c; 我尝试过使用 “任务计划” 设置开机启动 frpc&#xff0c; 但是失败了。 最后尝试使用 docker 开机启动 frpc 才成功&#xff0c; 因此本文主要介绍使用 docker …

【Git】(一)基本操作

读完本文后&#xff0c;您会了解&#xff1a; 1、如何在本地配置GIT环境&#xff1f; 2、环境配置成功后&#xff0c;如何从远端下载一个已有仓库到本地? 1. 配置全局用户名、邮箱 git config --global user.name "username" git config --global user.email &q…

解决方案:如何在 Amazon EMR Serverless 上执行纯 SQL 文件?

长久已来&#xff0c;SQL以其简单易用、开发效率高等优势一直是ETL的首选编程语言&#xff0c;在构建数据仓库和数据湖的过程中发挥着不可替代的作用。Hive和Spark SQL也正是立足于这一点&#xff0c;才在今天的大数据生态中牢牢占据着主力位置。在常规的Spark环境中&#xff0…

[oneAPI] Neural Style Transfer

[oneAPI] Neural Style Transfer oneAPINeural Style Transfer特殊环境定义使用包加载数据Neural Style Transfer模型与介绍训练过程结果 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI&#xff1a;https://devcl…

Kafka 入门到起飞 - 什么是 HW 和 LEO?何时更新HW和LEO呢?

上文我们已经学到&#xff0c; 一个Topic&#xff08;主题&#xff09;会有多个Partition&#xff08;分区&#xff09;为了保证高可用&#xff0c;每个分区有多个Replication&#xff08;副本&#xff09;副本分为Leader 和 Follower 两个角色&#xff0c;Leader副本对外提供读…

做海外游戏推广有哪些条件?

做海外游戏推广需要充分准备和一系列条件的支持。以下是一些关键条件&#xff1a; 市场调研和策略制定&#xff1a;了解目标市场的文化、玩家偏好、竞争格局等是必要的。根据调研结果制定适合的推广策略。 本地化&#xff1a;将游戏内容、界面、语言、货币等进行本地化&#…

SpringBoot复习:(42)WebServerCustomizer的customize方法是在哪里被调用的?

ServletWebServletAutoConfiguration类定义如下&#xff1a; 可以看到其中通过Import注解导入了其内部类BeanPostProcessorRegister。 BeanPostProcessor中定义的registerBeanDefinition方法会被Spring容器调用。 registerBeanDefinitions方法调用了RegistrySyntheticBeanIf…

【C++】面向对象编程引入 ③ ( 面向过程编程的结构化程序设计方法 | 结构化程序设计方法概念 / 特点 / 优缺点 | 面向对象编程引入 )

文章目录 一、面向过程编程的结构化程序设计方法1、结构化程序设计方法概念2、结构化程序设计方法特点3、结构化程序设计方法优缺点 二、面向对象编程引入 一、面向过程编程的结构化程序设计方法 如果使用 面向过程语言 ( 如 : C 语言 ) , 开发 大型 项目 , 一般使用 结构化程序…

什么是字体堆栈(font stack)?如何设置字体堆栈?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是字体堆栈&#xff08;Font Stack&#xff09;&#xff1f;⭐ 如何设置字体堆栈&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 …