希尔排序算法(思路分析)

希尔排序也称之为: 缩小增量排序

希尔排序提出的背景:

因为简单插入排序中存在一些问题( 这里我们以升序排序为例 ): 当我们要待插入的数值比较小时后移的次数明显增多,对效率有比较大的影响,所以我们就提出了希尔排序

希尔排序算法介绍:

希尔排序是希尔(Donald shell)于1959年提出的一种排序算法,希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更加高效的版本 , 也称之为 : 缩小增量排序

希尔排序的基本思想:

希尔排序是把记录按下标的一定增量分组,对每个组使用直接插入排序算法进行排序,随着增量主键减小,每组中包含的关键词越来越多,当增量减少到1的时候,整个就会被分为一组,然后就对这一组进行一次直接插入排序,然后算法变终止了

希尔排序算法思路图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6IAVrS7-1661005216498)(E:\非凡英才\数据结构(java)]\数据结构图解\插入排序过程图解.png)

希尔排序分为两种:

  1. 交换式
  2. 位移式

这个就是因为我们的直接插入排序也是有这两种方式,但是我们一般都是使用位移式,不会选择使用交换式,因为交换式和冒泡排序有些类似,执行效率太低,所以我们一般都是使用的位移式,所以这里我们也就是对位移式的希尔排序进行一个讲解

希尔排序的思路分析:

我们首先要知道希尔排序算法的实现是要通过三层for循环来实现的,因为我们的希尔排序就是在每次分组的基础上进行一个直接插入排序,而直接插入排序我们要使用两层循环(外层for循环 + 内层while循环)来解决,而对于我们的分组,也就是自增变量的缩小我们也要通过一层for循环来实现

  • 我们首先要定义一个整形变量表示增量 (一般就是定义一个 int gap ), 并来逐步的进行缩小增量,最开始的时候我们的增量是length/2,增量也就等于我们的分组数,也就是最开始的时候就是有length-2组,这个时候注意 :

    • 我们这里说的组是要进行排序的元素分为一组,也就是要进行直接插入排序的元素分为一组,那么每个元素和那些元素是一组? 这个元素的索引位置加上后者减去增量(gap)之后对应位置的元素就是和自己一组的元素
  • 然后就对每一组进行一个直接插入排序,等把length /2组的都进行直接插入排序之后,我们就将增量设置为length/4,就是有length/4组,然后再重复上述的操作,知道最后分为了一组之后再执行一次插入排序那么算法就算是结束了
    • 那么我们如何实现组内的直接插入排序?

      • 我们还是定义一个临时变量记录待插入元素,再定义一个临时变量记录待插入的位置的索引

        • 注意: 这个时候待插入元素不是从数组中第二个元素开始,而是从第一组的第二个元素开始,那么第一组的第二个元素在什么位置?

          • 我们前面已经说过了我们的每一个元素加上增量就是我们的组内的下一个元素,这个时候我们的第一组的第一个元素肯定是索引为0的元素,那么对应的我们就可以计算出我们的第一组中第二个元素就是索引为gap的元素

            • 那么具体的我们要如何实现?我们的待插入元素如何变化, 我们的待插入位置如何变化,我们的数值如何后移?

              • 我们每次待排序元素变换的时候都是后移一位即可,一个拍完了之后就继续拍下一个就可以了,因为每个组的元素我们都要进行排序, 而对于每次带插入位置前移的时候或者是待插入位置元素后移的时候都是移动gap位, 因为我们这个时候直接插入排序我们不是和前面一位的元素进行比较,而是要和前gap位的元素进行比较,就是要变化gap位, —> 因为我们的每个元素加上或者减去gap之后所得到的位置就是我们的同一个组内的元素位置了

                • 这个时候我们还有一个小算法: 移动次数 = 间隔数 + 1

总结: 直接插入排序中待插入元素的位置和待插入位置变换的时候都是变换一位,而在希尔排序中我们的待插入元素的位置变换的时候是变换一位,但是在希尔排序中我们的待插入位置前移的时候要前移 gap(增量)位

补充:

  1. 我们定义的gap变量就是表示我们希尔排序中的增量,增量其实也就等于分的组的个数,我们的增量是在length/2之间的,包括length/2和1,所以这个时候我们判断分组退出的条件就是当我们的gap(增量) = 0,这个时候等于0就会退出,那么我们就要让这个循环的判断条件为gap>0,这个时候如果gap=0的时候就会退出循环了

    • 关于增量的变换我们一般都是每次都让增量值除以2
  2. 希尔排序中要定义的变量和我们的直接插入排序中定义的变量是一样的,因为我们的希尔排序就是在分组的基础上进行了一个直接插入排序

  • 也就是我们的希尔排序中也是定义如下两个变量:

    1. int insertVal = 0; //这里只是定义,但是赋值的时候insertVal也是应该等于0的,但是我们在我们后续的算法中将insertVal的值赋值为了gap,这个时候沃恩的insertVal就不是表示我们的待插入位置的前一个位置,而是直接就是我们的待插入位置
      
    2. int insertIndex = 0: //这里只是定义,具体赋值的时候我们是将insertIndex的值赋值为: gap
      

算法核心:

问题引出: (为什么要提出希尔排序?)

希尔排序就是在直接插入排序的基础上做了一个升级, 我们之前讲过: 简单直接插入排序算法的缺点就是当我们的待排序序列趋于逆序的时候这个时候我们要做的位移或者交换就会有很多次, 效率就会比较低(这里说的位移就是直接将元素后移, 交换就是将元素的位置交换), 如果是使用的交换式的直接插入排序, 如果是遇到完全逆序的情况, 其时间复杂度会和冒泡排序差不多, 都是非常低的, 所以为了解决这个问题, 为了能一定程度的提高直接插入排序算法的时间复杂度, 我们就在简单直接插入排序的基础上提出了希尔排序

算法核心:

希尔排序就是一个逐渐缩小增量的直接插入排序, 就是先将整个待排序序列分成多个序列, 然后在每个序列中进行一个直接插入排序, 然后最终增量将会一直缩小, 直到最终的时候我们的增量会缩小到1, 这个时候我们的序列就会是整个的一个序列, 那么这个时候我们进行一个简单直接插入排序的时候由于我们的序列的混乱度比较低, 这个时候算法(也就是我们的简单直接插入排序的算法时间复杂度就会很高)

  • 所以其实我们的希尔排序就是先使用缩小增量的方式, 从而能够逐渐使用较少的局部的简单直接插入排序来降低我们整个待排序序列的混乱度, 从而减少了元素位移或者是交换的次数, 那么元素的位移和交换少了之后我们的算法的时间复杂度就会降低, 算法的效率想对与直接插入排序就会提高

希尔排序算法(思路分析) [数据结构][Java]相关推荐

  1. 冒泡排序算法(思路分析) [数据结构][Java]

    冒泡排序算法(思路分析) 基本介绍: 冒泡排序(Bubble Sorting)的基本思想是: 通过对 "待排序序列" 从前向后一次比较相邻元素的值,若发现逆序则交换,使值较大的元素 ...

  2. java实现apriori算法_各种排序算法的分析及java实现(一)

    阅读本文约需要7分钟 大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了下用Navicat for Mysql导入.sql文件的 ...

  3. dv算法java实现_各种排序算法的分析及java实现(二)

    更多精彩,请点击上方蓝字关注我们! 上次跟大家分享了下各种排序算法的分析及java实现(一)的相关知识,今天跟大家分享各种排序算法的分析及java实现(二)的知识.昨天我们讲到了选择排序,今天我们继续 ...

  4. java排序算法大全_各种排序算法的分析及java实现

    排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于要找工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究 ...

  5. 各种排序算法的分析及java实现 - 残剑_ - 博客园

    排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间 ...

  6. java代码实现希尔排序_Java希尔排序算法代码实现

    Java希尔排序算法代码实现 时间:2017-08-30     来源:华清远见JAVA学院 什么是Java希尔排序算法呢? 希尔排序算法实际上是一种分组插入的排序算法,又被称为缩小增量排序.今天华清 ...

  7. 排序算法:希尔排序算法实现及分析

    希尔排序算法介绍 希尔排序是D.LShell 与1957年提出来的一种排序算法,在这之前排序算法的时间复杂度都是O(n^2),希尔排序算法是突破这个时间复杂度的第一批算法之一.我们知道直接插入排序算法 ...

  8. java插入排序实现,经典(Java版)排序算法的分析及实现之一直接插入排序

    预备知识 排序算法从功能上是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列.从内存空间使用简单上看分为内部排序和外部排序. 内部排序是数据记录在内存中进行排序,适合不太大的元素序列 ...

  9. 排序算法 之希尔排序及时间复杂度分析

    排序算法之 冒泡排序及性能优化(时间复杂度+空间复杂度分析) 排序算法之 简单选择排序及时间复杂度分析 排序算法之 直接插入排序及时间复杂度分析 希尔排序 算法思想:将整个待排序列分割成若干个子序列( ...

最新文章

  1. python时间序列峰值检测_python – 二维数组中的峰值检测
  2. Deno 并不是下一代 Node.js
  3. C#内存映射文件学习总结
  4. Android中使用GridView实现标签效果源码
  5. iOS开发tips总结
  6. python中def fun(a、b=200)_python中的函数的参数和可变参数
  7. SpringBoot项目redis的消息队列
  8. Jqgried树形列表
  9. !--more--搭建的博客设置主页内容高度
  10. 记一次复杂的正则匹配——匹配但不包含
  11. .net反编译工具ILSpy
  12. 解决windows资源管理器卡死,右键无响应问题
  13. 谷歌图片的爬虫库(附加必应图片爬虫)--针对近期谷歌变了
  14. 前端人不可错过的低代码神器,告别切图,一键成稿啦!
  15. Python --- 输入、输出、运算符
  16. 菜鸟用编辑器做传送门——kura酱长期更新
  17. 学生学籍管理系统_学生登陆系统查询与修改信息
  18. Ardupilot 绕圈模式分析
  19. 流量统计工具 Piwik 简介
  20. Content Distribution Networks(CDNs)

热门文章

  1. 前端图片存储服务——果创云
  2. Kubernetes集群服务发现Service资源LoadBalancer类型详解(二十九)
  3. 用python写网络爬虫-爬取新浪微博评论
  4. 数组push时 覆盖的问题
  5. 探境科技荣膺清华校友三创大赛二等奖 初显峥嵘
  6. 数据中台即服务——数据中台的四大支柱
  7. MySql中的longtext字段的返回问题
  8. 直线和抛物线的运动规划
  9. docker挂载nginx配置文件
  10. SpringMVC3----@Controller注解、RestFul风格的讲解和应用、SpringMVC的接受请求参数、网页跳转方式和数据回显、乱码问题