引言

希尔排序的名称来源于它的发明者Donald Shell,是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

思路

希尔排序将整个待排序序列视为一个矩阵逐列各自进行(插入)排序w-sorting

若矩阵当前宽度为w,那么各自排序称为w-sorting

过程:

  • 将整个无序序列分割成若干个子序列(重排矩阵,由相隔某个“增量”的元素组成的)分别进行直接插入排序(若矩阵的每一列都已经经过了排序,则称之为w-ordered)
  • 然后依次缩小增量再进行排序(使矩阵变窄),待整个序列中的元素基本有序时,再对全体元素进行一次直接插入排序(如此往复,直到矩阵变成一列1-sorting)
  • 其中,增量为矩阵宽度构造的逆序列 {w1=1,w2,… }\{w_1=1,w_2,\dots\}{w1​=1,w2​,…}

下面来分析一个实例:

数组大小为13,我们将增量初始设置为长度/2,然后不停的除2直到为0。

首先,宽度13/2 = 6,那么矩阵宽度为6,首先将一维数组构造成一个矩阵,列数为6,行数未知。


构造方法也很简单,取6个元素放在第1行,再取6个放在第2行…

构造成的矩阵如上,每行给定不同的颜色,为了区分。初始数组可以看出是13X1的矩阵,这里我们把它变成了类似6X3的矩阵(为什么说类似,因为第3行没填满嘛)。

逐列进行(插入)排序6-sorting


上图左边是插入排序后的结果,右边是矩阵还原成一维数组的结果。注意到我们的数组中有两个16,经过此次排序,最后一个16到了最前面,因此可以看出该算法是不稳定的。

宽度6/2=3:

转换为矩阵,并排序:


上图1转换矩阵;图2对每列进行排序;图3是转换成数组。可以感受到,进行插入排序并不需要交换太多的元素。插入排序很适合于这种基本有序的数组。

宽度3/2=1:

宽度为1的矩阵可以看成是立起来的一维数组,所以现在只需要对该数组进行插入排序即可。

最终结果为:

其中,橙色的元素是发生往前插的元素。最终,得到一个排序序列。

代码

/*** 是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。* <p>* 将整个无序序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,* 然后依次缩小增量再进行排序,待整个序列中的元素基本有序时,再对全体元素进行一次直接插入排序。* <p>* 初始增量为数组长度/2,然后增量不停的缩小一半,直到为0* @param a* @param <E>*/
public static <E extends Comparable<? super E>> void shellSort(E[] a) {int j;for (int gap = a.length/2; gap > 0 ; gap/= 2) {//初始增量为数组长度/2,然后增量不停的缩小一半,直到为0for (int i = gap; i < a.length; i++) {//子序列分别进行直接插入排序//进行直接插入排序E tmp = a[i];for (j = i; j >= gap && tmp.compareTo(a[j - gap]) < 0 ; j-= gap) {a[j] = a[j - gap];}a[j] = tmp;}// System.out.println("gap=" + gap +"," + Arrays.toString(a));}
}

其中,该部分代码是和直接插入排序很类似的,因此先要理解插入排序的思想。

E tmp = a[i];
for (j = i; j >= gap && tmp.compareTo(a[j - gap]) < 0 ; j-= gap) {a[j] = a[j - gap];
}
a[j] = tmp;

复杂度和稳定性

  • 时间复杂度
    希尔排序中对于增量序列的选择十分重要,直接影响到希尔排序的性能。我们上面选择的增量序列,其最坏时间复杂度依然为O(N2)O(N^2)O(N2),一些经过优化的增量序列如Hibbard,经过证明可使得最坏时间复杂度为O(N32)O(N^\frac{3}{2})O(N23​),。

  • 稳定性
    非稳定算法

排序算法之——希尔排序分析相关推荐

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

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

  2. JAVA排序算法之希尔排序

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

  3. C/C++排序算法(2)希尔排序

    常见排序算法总结(2)希尔排序 一篇文章,带你搞懂 希尔排序 (注:代码语言的选择不应该限制了我们对算法的理解) 文章附有动图!一看就懂! (1)工作原理 希尔排序,也称递减增量排序算法,是插入排序的 ...

  4. 经典排序算法之希尔排序

    排序:希尔排序(算法) 一.简介 希尔排序(Shell Sort)是插入排序的一种算法,是对直接插入排序的一个优化,也称缩小增量排序. 希尔排序是非稳定排序算法. 希尔排序因DL.Shell于1959 ...

  5. [算法]-排序算法之希尔排序

    希尔排序算法思想 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序. 基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序 ...

  6. 排序算法之希尔排序(Java实现)

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

  7. 排序算法(4)希尔排序

    排序算法(4)希尔排序 原理: 希尔排序也称缩小增量排序:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序, 随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时(用gap ...

  8. php取名字算法,JavaScript排序算法之希尔排序的2个实例_基础知识

    插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率. 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位. 希尔排序按其设计者希尔(Donald Shell)的 ...

  9. 常见排序算法之希尔排序

    文章目录 1.概述 2.希尔排序之交换法 3.希尔排序之移动法 4.测试案例 1.概述 由于简单的插入排序每次数据量变多的时候,数据需要移动且交换数据的次数也会变多,继而影响效率.希尔排序就是在这个基 ...

  10. 我的Java开发学习之旅------gt;Java经典排序算法之希尔排序

    一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔 ...

最新文章

  1. Java业务代表模式
  2. 小米6鲁大师html5评测,一加6T依然是顶级旗舰!鲁大师2018手机性能榜跑分排前三!...
  3. 【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity
  4. Indri和Terrier搜索引擎的使用
  5. v-model详细使用
  6. 如何使用python爬取百度图片_【Python】爬取百度图片进行人脸识别
  7. 每天学点linux之-rmdir,cp,mv
  8. 3D游戏引擎设计 实时计算机图形学的应用方法 第2版 pdf 带索引书签目录
  9. java 缓存接口,java项目中,针对缓存问题的处理方式【接口中的处理方式】
  10. itextsharp c# asp.net 生成 pdf 文件
  11. html字体闪烁模板,CSS+JS阴影闪烁文字
  12. Python《突破JS动态加载,成功爬取漫画》
  13. html控件的id和name属性有什么不同
  14. 一种PLC RS485 Modbus RTU无线联网的解决方案
  15. Git基本介绍(三大分区及核心内部构造)
  16. thinkphp 关联模型配置代码
  17. 企业微信2.6.0发布 可与微信用户群聊了
  18. 15个mysql使用管理命令
  19. 对‘pthread_create’未定义的引用_2018年度‘龙虎榜’统计分析(一)
  20. 计算机学业水平考试反思总结8百,考试反思与总结

热门文章

  1. phpmailer 与 mail
  2. 20190823 尚硅谷MySQL核心技术
  3. 后缀数组三·重复旋律3
  4. 自定义获取焦点的TextView
  5. EasyUI DataGrid 添加排序
  6. IIS 10 安装URLRewrite组件 方式
  7. JIRA 饼图中文乱码
  8. Vert.x 异步访问数据库 MySQL
  9. 渗透小助手——几个密码收集工具
  10. MYSQL-常用函数