ds排序--希尔排序_图解直接插入排序和希尔排序

前言

这次我们介绍插入类排序中的 直接插入排序希尔排序

对于直接插入排序,虽然它的时间复杂度也是 O(n^2) ,但是在元素 有序或近乎有序 的情况下,时间复杂度可以降为 O(n) ,效率比 O(nlogn) 的算法还要高。

然而对于大规模的乱序数组,使用直接插入排序的效率是非常低的。此时我们需要使用希尔排序,希尔排序在直接插入排序的基础上,弥补了直接插入排序只能比较相邻元素的不足,使得可以按照指定步长比较元素,充分发挥了直接插入排序对于小规模有序数组排序的优势。

下面我们分别介绍 直接插入排序希尔排序 两类插入排序。

直接插入排序

有如下数组,我们需要对它从小到大排序,利用直接插入排序步骤如下:

566e0d3475bc2821d21cd038ba92e2ad.png
  1. 将第二个元素和第一个元素比较,小于第一个元素的话交换位置,这样第二个元素作为最小的元素排在了最前面,大于的话不交换。
  2. 然后将第三个元素和第二个元素比较,小于第二个元素的话交换位置,然后再和第一个元素比较,小于第一个元素的话再次交换位置,这样第三个元素作为最小的元素排在了最前面,大于的话不交换。
  3. 以此类推,直到最后一个元素插入到合适位置。

下图展示了整个排序的过程:

71e7de16283e8f4e4393cbcac92be08e.png

直接插入排序的代码:

public static void sort(Comparable[] arr) {    int n = arr.length;    // 0位置不需要比,从1到最后一个位置n-1    for (int i = 1; i <= n - 1; i++) {        for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--) {            swap(arr, j, j-1);        }    }}private static void swap(Object[] arr, int i, int j) {    Object t = arr[i];    arr[i] = arr[j];    arr[j] = t;}

优化

优化的思路就是将内循环中每次 swap 交换操作修改为 让较大的元素后移,最后再进行一次交换 ,这样一来访问数组的次数就减少了(交换需要三行,赋值只需要一行)。

优化步骤如下:

  1. 每次先保存当前插入的元素。
  2. 将当前保存的元素(第二个元素)和第一个元素比较,小于第一个元素的话,将第一个元素移动到第二个元素位置,然后当前保存的元素移动到第一个元素位置,这样第二个元素作为最小的元素排在了最前面。
  3. 将当前保存的元素(第三个元素)和第二个元素比较,小于第二个元素的话,将第二个元素移动到第三个元素位置,然后当前保存的元素移动到第二个元素位置,接着小于第一个元素的话再次执行以上操作,这样第三个元素作为最小的元素排在了最前面。
  4. 以此类推,直到最后一个元素插入到合适位置。

下图展示了优化思路的过程:

357085a0c534ca38c69bb3e4c6621555.png

优化的直接插入排序代码:

public static void sort(Comparable[] arr) {    int n = arr.length;    // 0位置不需要比,从1到最后一个位置n-1    for (int i = 1; i <= n - 1; i++) {        // 保存当前插入的元素        Comparable e = arr[i];        int j;        for (j = i; j > 0 && arr[j - 1].compareTo(e) > 0; j--) {            arr[j] = arr[j - 1];        }        arr[j] = e;    }}

希尔排序

上面我们介绍了直接插入排序,它对于大规模乱序数组的排序效率比较低,因为只能交换相邻的元素,所以元素只能一点一点地从数组的一端移动到另一端。此外,如果最小的元素在数组的末尾,那么将它插入到正确位置需要移动 N-1 次。

希尔排序的出现,解决了上述问题。它能够交换不相邻的元素以对数组的局部进行排序,并最终用直接插入排序将局部有序的数组排序。

希尔排序的思想是使数组中任意间隔为 h 的元素都是有序的。这样的数组也叫作 h 有序数组 。我们不研究 h 是如何得来的,这里直接使用了《算法》书中的 h 步长序列。

h = 3*h+1 ,根据 h 的取值分别为1、4、13 ...

实际上只需要把直接插入排序代码中移动元素的距离由 1 改为 h 即可。这样,希尔排序就转换为了一个类似于直接插入排序但使用不同增量的过程。

下图展示了希尔排序的过程:

8428de2e145e53ff8a82c583e09d5a50.png

如果你仔细观察,会发现在 h=1 时,相比直接插入排序,比较的次数大大减少了,这是因为希尔排序使得部分子数组有序,而直接插入排序对于近乎有序的数组,效率是非常高的。

希尔排序代码:

public static void sort(Comparable[] arr) {    int n = arr.length;    // 步长序列: 1, 4, 13...    int h = 1;    while (h < n / 3) {        h = 3 * h + 1;    }    while (h >= 1) {        for (int i = h; i < n; i++) {            // 将 arr[i] 插入到 arr[i-h], arr[i-2*h], arr[i-3*h]... 中            Comparable e = arr[i];            int j;            // 优化的插入排序            for (j = i; j >= h && e.compareTo(arr[j - h]) < 0; j -= h) {                arr[j] = arr[j - h];            }            arr[j] = e;        }        h /= 3;    }}

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

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

相关文章

jsf 配置_JSF Tomcat配置示例

jsf 配置JavaServer Faces (JSF)是一个Web应用程序框架&#xff0c;旨在简化基于Web的用户界面的开发集成。 它用于开发和构建服务器端用户界面组件&#xff0c;并在Web应用程序中使用它们。 JSF技术基于Model-View-Controller (MVC)架构&#xff0c;并且通过在页面中使用可重用…

无法加载可扩展计数器_多核可扩展计数器

无法加载可扩展计数器到处都需要计数器&#xff0c;例如&#xff0c;查找应用程序的关键KPI&#xff0c;应用程序的负载&#xff0c;服务的请求总数&#xff0c;用于查找应用程序吞吐量的一些KPI等。 由于所有这些需求&#xff0c;并发复杂性也增加了&#xff0c;这使这个问题…

linux忘记mysql密码_linux下忘记mysql root密码解决办法 | 系统运维

引言&#xff1a;在linux系统中&#xff0c;如果忘记了MySQL的root密码&#xff0c;有没有办法重新设置新密码呢&#xff1f;答案是肯定的&#xff0c;下面教大家一个比较简单的重置MySQL root密码的办法&#xff1a;1、编辑MySQL配置文件my.cnf系统运维www.osyunwei.com温馨提…

mysql中cast函数_mysql中cast函数的使用 用于强制类型转换 (转载)

例子&#xff1a;SELECTstr_to_date(concat(year(a.tb_time),date_format(a.tb_time,%m),01),%Y%m%d) tb_time,cast(a.category_id as char) category_id,a.category_name,sum(a.tendered_sum)/sum(a.winbid) tendered_sum,sum(a.winbid_sum)/sum(a.winbid) winbid_avgfrom( SE…

dht11温湿度传感器_Arduino不调用库实现DHT11数据读取

DHT11概述DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;它应用专用的数字模块采集技术和温湿度传感技术&#xff0c;确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件&#xff0c;并与一个高性…

rete_RIP RETE时间来获得PHREAKY

rete我刚刚完成了有关新规则算法PHREAK的高级文档&#xff0c;PHREAK是混合推理中的一个文字游戏。 它仍然有点粗糙和高水平&#xff0c;但希望仍然很有趣。 它建立在ReteOO之上&#xff0c;非常好阅读。 ReteOO算法 ReteOO是在3、4和5系列发行版中开发的。 它采用了RETE算法并…

java如果把字符串转成对象_Java中的重复对象:不仅仅是字符串

当Java应用程序消耗大量内存时&#xff0c;它本身就会出现问题&#xff0c;并可能导致GC压力增加和GC暂停时间过长。在我之前的一篇文章中&#xff0c;我讨论了Java中常见的内存浪费源&#xff1a;重复字符串。两个 java.lang.String 对象&#xff0c; a 并 b 在重复时 a ! b &…

批处理 设置电脑最佳性能_批处理最佳做法

批处理 设置电脑最佳性能大多数应用程序至少具有一个批处理任务&#xff0c;在后台执行特定的逻辑。 编写批处理作业并不复杂&#xff0c;但是您需要了解一些基本规则&#xff0c;我将列举一些我发现最重要的规则。 从输入类型的角度来看&#xff0c;处理项目可以通过轮询处理…

JVM体系结构:JVM类加载器和运行时数据区

各位读者好&#xff01; 在JVM系列的上一篇文章中&#xff0c;开发人员了解了Java虚拟机&#xff08;JVM&#xff09;及其体系结构。 本教程将帮助开发人员正确回答以下主题的问题&#xff1a; ClassLoader子系统 运行时数据区 1.简介 在继续之前&#xff0c;让我们看一下Ja…

mysql5.6特性_MySQL5.6新版本特性

MySQL已发布新的系列版本5.6.x&#xff0c;如果打算升级的朋友可以尝试&#xff0c;虽然目前没有收到新版本的使用反馈&#xff0c;但凭借MySQL占据市场份额来看&#xff0c;新版本的确值得期待。五大特性&#xff1a;优化器的改进MySQL Optimizer 团队做了大量的工作为了不断的…

java计算整数出现的次数_[剑指offer题解][Java]1到n整数中1出现的次数

前言众所周知&#xff0c;《剑指offer》是一本“好书”。如果你是个算法菜鸡&#xff08;和我一样&#xff09;&#xff0c;那么最推荐的是先把剑指offer的题目搞明白。对于剑指offer题解这个系列&#xff0c;我的写作思路是&#xff0c;对于看过文章的读者&#xff0c;能够做到…

mysql 更改root密码及 主机_设置更改root密码(远程,本地)、连接mysql、mysql常用命令...

设置更改root密码1、将mysql加入环境变量中[rootcentos7 ~]# grep mysql /etc/profileexport PATH/usr/local/mysql/bin/:$PATH2、直接登录&#xff0c;无密码[rootcentos7 ~]# mysql -uroot3、方式一&#xff1a;设置密码[rootcentos7 ~]# mysqladmin -uroot password 123456W…

从NetBeans运行和调试WildFly Swarm应用程序

使用NetBeans的Java EE开发人员习惯于直接在NetBeans所选择的应用程序服务器中运行和调试其瘦战应用程序。 在开发打包为ber或镂空jars的微服务时&#xff0c;您期望使用相同的轻松方式进行运行和调试。 好消息是您可以。 在本文中&#xff0c;我将逐步演示如何在NetBeans中运行…

hazelcast入门教程_Hazelcast入门

hazelcast入门教程7月&#xff0c;我写了一个博客向Java开发人员介绍erlang&#xff0c;重点介绍了这两种语言之间的一些异同。 erlang虚拟机具有许多令人印象深刻的内置功能&#xff0c;其中之一是它们独立于位置且可以相互通信。 这意味着可以通过编写很少的代码行在VM之间同…

[MEGA DEAL]完整的Java编程训练营(94%折扣)

成为Java Master的10门课程&#xff08;83.5小时&#xff09;&#xff1a;使用JavaFX的设计UI&#xff0c;利用设计模式&#xff0c;Master Multithreading等 嘿&#xff0c;怪胎&#xff0c; 本周&#xff0c;在我们的JCG Deals商店中 &#xff0c;我们提供了另一个超值优惠…

java重排序_Java内存模型FAQ(四)重排序意味着什么?

译者&#xff1a;Alex在很多情况下&#xff0c;访问一个程序变量(对象实例字段&#xff0c;类静态字段和数组元素)可能会使用不同的顺序执行&#xff0c;而不是程序语义所指定的顺序执行。编译器能够自由的以优化的名义去改变指令顺序。在特定的环境下&#xff0c;处理器可能会…

JVM体系结构101:了解您的虚拟机

Java虚拟机&#xff08;JVM&#xff09;架构和Java字节码101的初学者速成班 Java应用程序无处不在&#xff0c;它们在我们的手机&#xff0c;平板电脑和计算机上。 在许多编程语言中&#xff0c;这意味着要多次编译代码才能使其在不同的OS上运行。 对于作为开发人员的我们来说…

flask对mysql数据库增删改查_Flask学习(三) - Flask-SQLAlchemy对数据库增删改查

Flask-SQLAlchemy对数据库增删改查安装pip install flask-sqlalchemy具体不多说了&#xff0c;主要是对数据库进行简单的增删改查&#xff0c;上代码&#xff0c;看注释app.route(/)def index():#增加article1 Article(titletest1, contentthe first test)db.session.add(arti…

带有Jersey的JAX-RS教程,用于RESTful Web服务

在当今世界&#xff0c;数据扮演着非常重要的角色。 如此众多的应用程序将各种类型的数据用于不同的操作&#xff0c;所以最重要的方面是应用程序之间的通信。 当应用程序可以通信时&#xff0c;它们之间的数据共享变得容易。 就像在亚洲运行的应用程序向在欧洲运行的应用程序…

java swing 打开文件_java swing实现打开Excel文件并进行处理

这里选择Excel文件是业务需要&#xff0c;话不多说1、引入对Excel处理的相关依赖org.apache.poipoi3.16org.apache.poipoi-ooxml3.162、进行swing的相关布局代码&#xff1a;package com.mozarta;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.xssf.usermodel…