希尔排序

2023-10-26

希尔排序又称为缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

一、原理

既然希尔排序是插入排序的改进版本,那么它们之间必定有相似之处。那么得先回忆下什么是插入排序?插入排序就是将一个数组分为两个区间:已排序区间和未排序区间。然后在未排序区间中取一个数,将其按照顺序插入到已排序区间,重复操作,保证已排序区间一直有序。

希尔排序是将整个有序序列分割成若干小的子序列分别进行插入排序,使数组中任意间隔为n的元素都是有序的,这个间隔n称为增量

整个过程如下,首先设置一个增量大小,将原始序列中间隔为n的元素进行递增排序,使得这两个元素有序,接着对整个数组中所有元素都这样排序,当间隔为n的元素都有序之后,缩小增量,继续重复以上操作。

希尔排序用语言表述比较不直观,那就来看一张图,以数组{8,9,1,7,2,3,5,4,6,0}为例。

在增量=5时,首先进行排序的是(8,3)这一组数据,8>3,当(8,3)交换后,得到的序列为{3,9,1,7,2,8,5,4,6,0}。然后看看(8,3)这一组前面是否还有数据,发现没有了,于是进行下一组的排序。

下一组是(9,5),因为9>5,所以9和5进行交换,交换后的序列为{3,5,1,7,2,8,9,4,6,0},然后看看(9,5)这一组前面是否还有数据,发现还有一组我们上面排序后的(3,8),它们的顺序是对的,因此继续下一组的排序。

下一组是(1,4),因为1<4,所以1和4位置不变。然后看看(1,4)这一组前面是否还有数据,发现还有一组我们上面排序后的(3,8)和(5,9),它们的顺序是对的,因此继续下一组的排序。

重复以上操作,完成增量为5的排序后,将增量减少,继续下一次的排序,直到整个数组有序为止。

在这里插入图片描述

那么增量应该改什么值合适?一般来说,每次增量都除以2

二、示例代码

package Sort;
import java.util.Arrays;

public class ShellSort {
    public static void main(String[] args) {
        int[] arr = {8,9,1,7,2,3,5,4,6,0};
        shellSort(arr);
        System.out.println("arr = " + Arrays.toString(arr) );
    }

    public static void shellSort(int[] arr) {
        // 增量初始化为数组长度的一半,每次都/2
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
            //从增量位置那一组开始进行插入排序,直至完毕
            for (int i = gap; i < arr.length; i++) {
                int j = i;                 // 从i这个位置开始从后往前排序
                int temp = arr[j];         // 先保存i位置的元素值,用于交换
                // j - gap 就是代表与它同组的左边的元素
                // j - gap >= 0:不越界
                while (j - gap >= 0 && arr[j - gap] > temp) {
                    arr[j] = arr[j - gap];
                    j = j - gap;           // 这一组比较过了继续往前比较,确定前面也有序
                }
                arr[j] = temp;
            }
        }
    }

三、算法分析

平均时间复杂度 最好时间复杂度 最坏时间复杂度 空间复杂度 排序方式 稳定性
O(nlogn) O(nlog2n) O(n2 ) O(1) In-place 不稳定

希尔排序的性能无法准确量化,跟输入的数据有很大关系,其时间复杂度介于O(nlogn)O(n^2) 之间。对于大规模的序列(n>=1000),希尔排序都具有很高的效率。

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n2)好一些。

由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

希尔排序 的相关文章

  • Spring JDBC 模板。如何获取pl/sql脚本的结果变量

    我正在使用 NamedParameterJdbcTemplate 来运行 pl sql 脚本 但我不知道如何获取out变量的值 id out 提前致谢 String script declare begin if myFunc id in
  • Java Swing 应用程序消息对话框帮助

    我正在开发 Java Swing 应用程序 我需要创建一个如图所示的对话框 我不知道这个的名字 我无法解释 所以我附上一张照片 请告诉我这叫什么以及如何在我的 GUI 应用程序中创建它 给猫剥皮的方法不止一种 public final cl
  • 我在使用 JavaFX 绘制十字时遇到问题

    我正在尝试编写代码 在网格上对角绘制 3 个形状 前两个形状是正方形和圆形 我能做到 然而 第三种形状让我有些悲伤 我应该画一个十字 T 版本 而不是 X 每次我写出代码时 它看起来就像一个侧面 我知道我只是错过了一些简单的东西 但我真的很
  • 检查从 arrayadapter 获取的复选框

    我有标题清单 CheckBox 我想控制默认检查哪一个 所以我试图获得正确的视图并检查它 但由于某种原因它不起作用 知道为什么吗 form checkbox item xml
  • 如何在JavaFX中有效地滚动和缩放大图像?

    作为图像处理应用程序的一部分 我需要创建具有缩放 滚动和矢量叠加功能的简单查看器模块 图像相当大 40000x20000 这使得 ImageView 上的操作变慢 缓冲等 在 JavaFX 中处理巨大图像时 改善用户体验的最佳选项是什么 我
  • 如何将日期字符串解析为Date? [复制]

    这个问题在这里已经有答案了 如何将下面的日期字符串解析为Date object String target Thu Sep 28 20 29 30 JST 2000 DateFormat df new SimpleDateFormat E
  • Java 表达式树 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有相当于 net的 LINQ 下的表达式树JVM 我想实现一些类似 LINQ 的代码结构Scala
  • Eclipse 无法识别 persistence.xml 的内容

    我在 eclipse 中收到以下错误 persistence xml 文件没有可识别的内容 我的 persistence xml 文件在我的应用程序中工作得很好 但 eclipse 一直给我这个错误 我在移动文件并使用 m2eclipse
  • Java - 调整图像大小而不损失质量

    我有 10 000 张照片需要调整大小 因此我有一个 Java 程序来执行此操作 不幸的是 图像的质量损失很大 而且我无法访问未压缩的图像 import java awt Graphics import java awt AlphaComp
  • 在 libgdx 中渲染 box2d

    我有一个使用 FitViewport 的大小为 800x480 的游戏世界 并且最初使用像素渲染 box2d 实体 固定装置 因此所有物理效果都显得浮动且缓慢 查看文档后 我意识到 box2d 使用度量单位 因此我将 box2d 位置和大小
  • ThreadPoolExecutor 和队列

    我以为使用线程池执行器 http docs oracle com javase 6 docs api java util concurrent ThreadPoolExecutor html我们可以提交Runnables 要在以下位置执行B
  • 如何在java中从包含.0的浮点数中删除小数部分

    我只想删除包含的浮点数的小数部分 0 所有其他数字都是可以接受的 例如 I P 1 0 2 2 88 0 3 56666 4 1 45 00 99 560 O P 1 2 2 88 3 567 4 1 45 99 560 有什么方法可以做到
  • Jersey 和 Spring 中的全局异常处理?

    我正在使用 Jersey 和 Spring 3 2 以及 Open CMIS 开发 RESTful Web 服务 我没有使用 Spring 的 MVC 模式 它只是 Spring IOC 和 Jersey SpringServlet 控制器
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算
  • 在 Apache Servicemix 4 中的 OSGi 包之间共享配置文件?

    有人能够在 SMX4 中的两个或多个捆绑包之间成功共享配置吗 我正在寻找的是这样的 有一个文件 SMX HOME etc myconfiguration cfg 使此配置 可用 以便使用 Spring dm 通过 OSGi 配置管理将其注入
  • Java DNSLookup MX 记录列表。类似于 MXToolBox

    我正在构建一个程序来列出域的所有 MX 记录 起初似乎工作正常 但与在线工具进行比较后http mxtoolbox com http mxtoolbox com 有些域程序无法获取 MX 记录 而 MXToolbox 可以 我不确定原因是什
  • Web 服务客户端的 AXIS 与 JAX-WS

    我决定用Java 实现Web 服务客户端 我已经在 Eclipse 中生成了 Axis 客户端 并使用 wsimport 生成了 JAS WS 客户端 两种解决方案都有效 现在我必须选择一种来继续 在选择其中之一之前我应该 考虑什么 JAX
  • java mysql 准备好的语句

    我正在尝试使用 java 向数据库中进行简单的插入 它告诉我我的 sql 语法已关闭 但是 当我复制打印出来的字符串并将其放入 phpmyadmin 中的 sql 命令中时 它会正确执行该命令 并且我似乎无法弄清楚 java 中的字符串查询
  • Volley 在第一次调用方法时返回 null

    我正在尝试使用 volley 从服务器检索数据 但是当我第一次调用此方法时 我收到服务器的响应 但该方法返回 null 如果我第二次调用它 我会得到最后的响应 public String retrieveDataFromServer Str
  • 需要在没有wsdl的情况下调用soap ws

    我是网络服务的新手 这个网络服务是由 siebel 提供的 我需要调用一项网络服务 我的客户向我提供了以下详细信息 这是 SOAP 对于产品 请使用它作为端点 Request

随机推荐

  • PHP取整,四舍五入取整、向上取整、向下取整、小数截取。

    PHP取整数函数常用的四种方法 1 直接取整 舍弃小数 保留整数 intval 2 四舍五入取整 round 3 向上取整 有小数就加1 ceil 4 向下取整 floor 一 intval 对变数转成整数型态 intval如果是字符型的会
  • 迭代器iterator

    能进行算术运算的迭代器只有随即访问迭代器 要求容器元素存储在连续内存空间里 vector string deque的迭代器是有加减法的 但是map set multimap multiset的迭代器是没有加减法的 list也不可以
  • minio老版本集成到k8s的yaml

    apiVersion apps v1 kind StatefulSet metadata name minio spec replicas 1 serviceName minio selector matchLabels name mini
  • Android WebView使用详解及注意事项

    未经本人授权 不得转载 否则必将维权到底 目前很多公司的 App 就只使用一个 WebView 作为整体框架 App 中的所有内容全部使用 HTML5 进行展示 这样只需要写一次 HTML5 代码 就可以在 Android 和 iOS 平台
  • Android textAppearance的属性设置及TextView属性详解

    http blog csdn net jaycee110905 article details 8762238 textAppearance的属性设置 android textAppearance android attr textAppe
  • html实现蜂窝菜单

    效果图 CSS样式 keyframes fade in mkmxd 1 0 filter blur 20px opacity 0 to filter none opacity 1 keyframes drop in mkmxd 1 0 tr
  • 【图片+代码】:GCC 链接过程中的【重定位】过程分析

    目录 示例代码 sub o 文件内容分析 段信息 符号表信息 main o 文件分析 段信息 符号表信息 绝对寻址 相对寻址 重定位表信息 可执行程序 main 段信息 符号表信息 绝对地址重定位 相对地址重定位 总结 别人的经验 我们的阶
  • 看京东架构师如何解决,数据库读写分离与事务纠缠的坑

    本篇文章讨论在数据库读写分离时使用事务的那些坑 1 在读写分离时会不会造成事务主从切换错误 一个线程在Serivcie时Select时选择的是从库 DynamicDataSourceHolder中ThreadLocal对应线程存储的是sla
  • SD卡学习笔记

    每个sector为512B 与IDE磁盘一样 通过读写命令读取一个多个sector 主控程序不需要关注SD具体是怎么实现读写与擦写的 每个sector可以耐受100 000次写操作 无限次读操作 每当sector被用命令erase命令擦除了
  • 三星被曝因ChatGPT泄露芯片机密!韩媒惊呼数据「原封不动」直传美国,软银已禁止员工使用...

    点击上方 AI遇见机器学习 选择 星标 公众号 第一时间获取价值内容 明敏 萧箫 发自 凹非寺 量子位 公众号 QbitAI 三星引入ChatGPT不到20天 就发生3起数据外泄事件 其中2次和半导体设备有关 1次和内部会议有关 消息一经释
  • Java 单测—static方法

    单测 static方法 静态方法的单测 静态方法的单测 方法上加注解 PrepareForTest 静态方法所在的类 class 调用测试方法前先要mock出类 Before public void setUp throws Excepti
  • 爱可生MySQL开源数据传输中间件DTLE首次技术分享

    10月27日 上海爱可生信息技术股份有限公司赞助的 3306 技术 Meetup 武汉站成功举办 爱可生技术服务总监洪斌分享了 MySQL 开源数据传输中间件架构设计实践 的主题演讲 并对爱可生10月24日最新开源项目 DTLE 相关技术细
  • Java岗面试:美国java程序员要求

    正文 在写这个文章之前 我花了点时间 自己臆想了一个电商系统 基本上算是麻雀虽小五脏俱全 我今天就用它开刀 一步步剖析 我会讲一下我们可能会接触的技术栈可能不全 但是够用 最后给个学习路线 Tip 请多欣赏一会 每个点看一下 看看什么地方是
  • cpu的架构

    明天继续搞一下cache 还有后面的 下面是cpu框架图 开始解释cpu 1 控制器 控制器又称为控制单元 Control Unit 简称CU 下面是控制器的组成 1 指令寄存器IR 是用来存放当前正在执行的的一条指令 当一条指令需要被执行
  • 单线程 JavaScript 的异步机制与经典 for 循环面试题

    从一个经典的 for 循环问题开始 for var i 1 i lt 5 i setTimeout function timer console log i i 1000 输出是 每隔1秒 输出一个6 共5次 原理 这样的输出 是由 Jav
  • 逆矩阵的性质

    矩阵的逆矩阵具有许多有用的性质 1 如果MM 1 I 则M 1M I 2 M1M2 1 M2 1M1 1 3 M 1 1 M 4 M 1 1 M 1 0 说明 M 1 表示矩阵M的逆 摘自 lt lt 计算机图形学几何工具算法详解 gt g
  • 测试工作内容(一)---需求分析

    当我们要做一个项目时 不管项目是一个大的软件 还是一个小的功能模块 我们在执行之前都要搞清楚 这个项目是做什么的 将会实现哪些功能需求 在时间点范围内需要我们做什么 做哪些工作 所追溯的就是需求 需求分析都需要做哪些事情 怎样做 包括以下四
  • JAVA注释

    单行注释 单行注释 多行注释 多行注释 文档注释 文档注释 放在类定义 方法 field 内部类之前才有效 此行前面这个星号只是为了好看 只有第一行和最后一行的 和 才有效 文档注释可以被javadoc命令抽取出api文档格式 javado
  • 木马编程-手把手带你进入木马的世界之木马编程

    一 基础知识 1 1 木马病毒 木马 Trojan 这个名字来源于古希腊传说 荷马史诗中木马计的故事 Trojan一词的本意是特洛伊的 即代指特洛伊木马 也就是木马计的故事 木马会想尽一切办法隐藏自己 主要途径有 在任务栏中隐藏自己 这是最
  • 希尔排序

    目录 一 原理 二 示例代码 三 算法分析 希尔排序又称为缩小增量排序 是直接插入排序算法的一种更高效的改进版本 希尔排序是基于插入排序的以下两点性质而提出改进方法的 插入排序在对几乎已经排好序的数据操作时 效率高 即可以达到线性排序的效率