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

🌟个人博客: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.mzph.cn/news/35686.shtml

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

相关文章

手撕数据结构之栈+例题

目录 一、栈的概念及结构 二、栈的头文件及基本框架 三、接口实现 1、对栈的初始化 2、栈的销毁 3、入栈操作 4、出栈操作 5、判断栈是否为空 6、返回栈顶元素 7、遍历栈 四、有效的括号 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 思路&#xff…

静态网页和动态网页区别

1&#xff0c;静态网页和动态网页有何区别 1) 更新和维护 静态网页内容一经发布到网站服务器上&#xff0c;无论是否有用户访问&#xff0c;这些网页内容都是保存在网站服务器上的。如果要修改网页的内容&#xff0c;就必须修改其源文件&#xff0c;然后重新上传到服务器上。…

k8s-----集群调度

目录 一&#xff1a;调度约束 二&#xff1a;Pod 启动创建过程 三&#xff1a;k8s调度过程 1、Predicate 有一系列的常见的算法 2、常见优先级选项 3、指定调度节点 &#xff08;1&#xff09;nodeName指定 &#xff08;2&#xff09;nodeSelector指定 四&#xff1a;亲和…

C++——继承

文章目录 &#x1f99c;1. 什么是继承&#x1f40a;1.1 概念&#x1f40a;1.2 格式&#x1f40a;1.3 继承方式 & 访问限定符 &#x1f426;2. 派生类和基类的赋值问题&#x1f9a9;3. 派生类和基类同名成员问题&#x1f413;4.派生类默认成员函数&#x1f409;4.1 构造函数…

React源码解析18(1)------ React.createElement 和 jsx

1.React.createElement 我们知道在React17版本之前&#xff0c;我们在项目中是一定需要引入react的。 import React from “react” 即便我们有时候没有使用到React&#xff0c;也需要引入。原因是什么呢&#xff1f; 在React项目中&#xff0c;如果我们使用了模板语法JSX&am…

单调递增的数字——力扣738

文章目录 题目描述解法题目描述 解法 #include<iostream> #include<string>using namespace std;int monotoneIncreasingDigits

中小企业项目管理软件推荐:选择适合的工具提升项目效率!

中小企业项目管理软件有哪些&#xff1f;Zoho Projects是一款好用无广告的项目管理软件。当个小创业者是真的不容易&#xff0c;不仅要管理团队&#xff0c;还要管理团队项目。很多团队之前用了好多项目管理的软件&#xff0c;但是都不太满意。但是如果你经常参加创业者聚会上&…

常见的路由协议之RIP协议与OSPF协议

目录 RIP OSPF 洪泛和广播的区别 路由协议是用于在网络中确定最佳路径的一组规则。它们主要用于在路由器之间交换路由信息&#xff0c;以便找到从源到目标的最佳路径。 常见的路由协议&#xff1a; RIP (Routing Information Protocol)&#xff1a;RIP 是一种基于距离向量算…

使用wxPython和PyMuPDF在Python中显示PDF目录的实现

展示如何使用wxPython和PyMuPDF库在Python中选择PDF文件并将目录显示在列表框中。 简介&#xff1a; 在本篇教程中&#xff0c;我们将学习如何使用wxPython和PyMuPDF库在Python中选择PDF文件&#xff0c;并将其目录显示在一个列表框中。这将使用户能够方便地浏览PDF文档的目录…

Golang 局部变量、全局变量 声明

文章目录 一、局部变量二、全局变量 一、局部变量 四种声明方式 多变量声明&#xff1a; package mainimport "fmt"//局部变量声明 func main() {//方法一: 声明一个变量和数据类型&#xff0c;不初始化值&#xff1b;默认值为0&#xff1b;var lvA intfmt.Printl…

【MybatisPlus】LambdaQueryWrapper和QueryWapper的区别

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

电路基础之电容

电容器&#xff08;Capacitor&#xff09;是由两个导体电极之间夹着一个电介质而组成的元件。这两个电极可以是金属板、箔片、涂层等&#xff0c;而电介质则是放置在电极之间的绝缘材料。电容器的基本构成包括以下几个要素&#xff1a; 电极&#xff1a;电容器的电极是两个导体…

js合并数组对象(将数组中具有相同属性对象合并到一起,组成一个新的数组)

一、根据数组对象中某一key值&#xff0c;合并相同key值的字段&#xff0c;到同一个数组对象中&#xff0c;组成新的数组 1.原数组&#xff1a; var array [{ id: 1, name: Alice },{ id: 2, name: Bob },{ id: 1, age: 25 },{ id: 3, name: Charlie, age: 30 } ];2.合并后数…

接口测试实战,Jmeter正则提取响应数据-详细整理,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在测试时&#xf…

服务器安装JDK

三种方法 方法一&#xff1a; 方法二&#xff1a; 首先登录到Oracle官网下载JDK JDK上传到服务器中&#xff0c;记住文件上传的位置是在哪里&#xff08;我放的位置在/www/java&#xff09;&#xff0c;然后看下面指示进行安装 方法三&#xff1a; 首先登录到Oracle官网下载…

基于STM32CUBEMX驱动TMOS模块STHS34PF80(1)----获取ID

基于STM32CUBEMX驱动TMOS模块STHS34PF80----1.获取ID 概述样品申请视频教程所有功能接口最小系统图生成STM32CUBEMX串口配置IIC配置IO口设置串口重定向 模块地址参考demoIIC写函数IIC读函数参考程序初始化获取ID主函数 概述 STHS34PF80 是一款非冷却、工厂校准的红外运动和存在…

端口输入的数据为什么要打拍?

一次作者在开发图像时候&#xff0c;对输入的图像没有打拍&#xff0c;直接输出给显示终端&#xff0c;时好时坏&#xff0c;或者图像颜色不正确&#xff0c;最终经过打拍解决了此问题。 //配置为16-Bit SDR ITU-R BT.656模式时pixel_data[23:16]为高阻。always (posedge pixe…

C#多线程开发详解

C#多线程开发详解 持续更新中。。。。。一、为什么要使用多线程开发1.提高性能2.响应性3.资源利用4.任务分解5.并行计算6.实时处理 二、多线程开发缺点1.竞态条件2.死锁和饥饿3.调试复杂性4.上下文切换开销5.线程安全性 三、多线程开发涉及的相关概念常用概念(1)lock(2)查看当前…

NanoPi NEO移植LVGL8.3.5到1.69寸ST7789V屏幕

移植前准备 移植好fbtft屏幕驱动 参考链接&#xff1a;友善之臂NanoPi NEO利用fbtft驱动点亮1.69寸ST7789V2屏幕 获取源码 名称地址描述lvglhttps://github.com/lvgl/lvgl.gitlvgl-8.3.5lv_drivershttps://github.com/lvgl/lv_drivers.gitlv_drivers-6.1.1 创建工程目录 创…

旋转图像(旋转矩阵)

原题链接 旋转图像备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/rotate-image/ 算法分析 若矩阵的行列数为N&#xff0c;设i表示行索引&#xff0c;i属…