一、算法思想

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
1)插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率;
2)插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位;

我们将数组中两个元素之间的距离称为Gap,相邻元素之间的Gap自然是1,很明显的,插入排序的算法在调节元素的时候,Gap是1,这就造成了上面讲的低效的原因2)。因此希尔排序的思想如下:

1)假设序列的元素个数是n,选取一个初始Gap的d(d<n);

2)将序列中元素之间距离(即Gap)为d的元素分为一组,在每组之间直接进行插入排序;

3)全部完成以后,缩小Gap至d1(d1<d),然后继续2)直到Gap为1;

常见的Gap序列如下:

1)希尔原本的Gap:N/2、N/4、...1(反复除以2)
2)Hibbard的Gap:1、3、7、...、2k-1(k表示第几个gap)
3)Knuth的Gap: 1、4、13、...、(3k - 1) / 2(k表示第几个gap)
4)Sedgewick的Gap: 1、5、19、41、109、...

二、算法示意图

如图所示,展示了分组和排序的过程。第一行是分组的过程,总共有8个元素,Gap为8/2=4,标记为相同颜色的元素为一组。第二行是同一组元素经过插入排序后形成的样子,可以看到,蓝色和灰色组元素进行了交换。第三行是Gap缩小为4/2=2的分组,相同颜色元素为一组,第四行是同组元素经过插入排序后形成的序列,可以看到每一组都是有序的。第五行是Gap缩小为2/2=1的分组,即整个数列为一个组,直接进行插入排序,这里就和插入排序完全一样了。

注意到第五行的时候,序列已经基本有序了,靠近插入排序的最优情况,所以插入排序的效率极高。

三、Java代码

 //@wiki
public class ShellSort extends Sort {
public static void sort(int array[]) {
int length = array.length;
int temp = 0;
for (int gap = length / 2; gap >= 1; gap = gap / 2)
for (int i = gap; i < length; i++)
for (int j = i; j >= gap && array[j] < array[j - gap]; j -= gap) {
temp = array[j];
array[j] = array[j - gap];
array[j - gap] = temp;
}
}
}

这段代码看上去比较复杂,因为嵌套着三层for循环,另外代码的想法和上面示意描述的并不一致,因此总是会比较难理解。

示意中讲:按照每一组进行插入排序,很容易让人想到一组组的去执行插入排序,然后一起再进行下一步。代码不是这样的,代码是所有组同时进行的,第7行可以看到,每次遍历都是从gap开始遍历到数列最后,然后对每一个元素进行往前进行插入排序,不过这次不是和前一个相邻元素作比较,而是和j-gap作比较,很容易发现,这其实是在元素所在组进行插入排序。

四、算法复杂度

其算法复杂度至今没有一个确定的解,其复杂度依赖于其Gap序列,范围Ο(n^1.5) ~ Ο(n^2)。而最好的情况则是序列初始状态就是顺序排列,此时算法的复杂度是O(n)。平均复杂度则为:Ο(n^5/4)。

空间复杂度非常容易,由代码可以看出来,只需要一个位置temp用于交换即可,因此是O(1)。

【DS】排序算法之希尔排序(Shell Sort)的更多相关文章

  1. 数据结构与算法之PHP排序算法(希尔排序)

    一.基本思想 希尔排序算法是希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接 ...

  2. 算法相关——Java排序算法之希尔排序(五)

    个子块,即{3,5},{1,0},{5,2},{9,4},{6,12},将每个子块进行插入排序(即第i位与第i+5位进行比较交换),初步排序结果为{3,0,2,4,6,5,1,5,9,12}.希尔排序 ...

  3. Java学习笔记——排序算法之希尔排序(Shell Sort)

    落日楼头,断鸿声里,江南游子.把吴钩看了,栏杆拍遍,无人会,登临意. --水龙吟·登建康赏心亭 希尔算法是希尔(D.L.Shell)于1959年提出的一种排序算法.是第一个时间复杂度突破O(n²)的算 ...

  4. 【排序算法】希尔排序算法 Java实现

    希尔排序算法是按其设计者希尔(Donald Shell)的名字命名,该算法由1959年公布,是插入排序的一种更高效的改进版本. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎 ...

  5. 我的Java开发学习之旅------>Java经典排序算法之希尔排序

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

  6. 排序算法之希尔排序的python实现

    希尔排序(Shell’s Sort)是插入排序的一种,是直接插入排序算法的一种更高版本的改进版本. 希尔排序的工作原理 如下: (1)把记录按步长gap分组,对每组记录采用直接插入排序方法进行排序: ...

  7. java排序算法之希尔排序

    希尔排序是冲破二次时间屏障的第一批算法之一. 它是通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到最后一趟(比较相邻元素)为止.因此希尔排序也叫缩减增量排序. 希尔排序使 ...

  8. 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)

    插入排序算法主要分为:直接插入算法,折半排序算法(二分插入算法),希尔排序算法,后两种是直接插入算法的改良.因此直接插入算法是基础,这里先进行直接插入算法的分析与编码. 直接插入算法的排序思想:假设有 ...

  9. js排序算法06——希尔排序

    希尔排序本质是一种插入排序,由一位叫希尔的大神提出得名,其基本思想是将数组分组进行插入排序,每次消除不止一个逆序对,这样就提高了插入排序的效率.最后一步进行一间隔的插入排序,此时数组已经基本有序.代码 ...

随机推荐

  1. 解决Docker容器时区及时间不同步的问题

    前几天在测试应用的功能时,发现存入数据库中的数据create_time或者update_time字段总是错误,其他数据都是正常的,只有关于时间的字段是错误的. 进入linux服务器中查看,也没有任何的 ...

  2. .NET Core容器化开发系列(一)——Docker里面跑个.NET Core

    前言 博客园中已经有很多如何在Docker里面运行ASP.NET Core的介绍了.本篇主要介绍一些细节,帮助初学的朋友更加深入地理解如何在Docker中运行ASP.NET Core. 安装Docke ...

  3. Jq_$.getJSON( )

    jQuery中的$.getJSON( )方法函数主要用来从服务器加载json编码的数据,它使用的是GET HTTP请求.使用方法如下: $.getJSON( url [, data ] [, succ ...

  4. 软件测试_测试工具_LoadRunner

    最近正在逐步学习软件测试工具的使用,此文章也是用来当做笔记以供记录之用.如有问题,还请多多指出. 安装LoadRunner基本步骤从网上搜索即可找到,特此提供部分链接参考(其中附带软件下载): 1.L ...

  5. selenium+python自动化----xlrd,xlswriter

    1.准备: 使用之前需要先按照:打开cmd,输入pip install xlrd(xlswriter),点击enter; 2.基本使用: xlrd: #打开els文件,参数是文件路径: table = ...

  6. 使用SignalR实时Web应用程序

    实时Web应用程序能够实时地将服务器端内容推送到连接的客户端.对于ASP.NET开发人员,ASP.NET SignalR是一个向其应用程序添加实时Web功能的库.它利用了多种传输方式,根据客户端和服务 ...

  7. EOS开发基础之四:使用cleos命令行客户端操作EOS——智能合约之eosio.bios和eosio.token

    现实世界中的合约,简单地说,是一个参与活动的所有人都需要遵循的协议.合约可以是正式的法律合同(例如,金融交易),或者是简单的游戏规则.典型的活动可以是诸如资金转移(在金融合约的情况下)或游戏动作(在游 ...

  8. PAT甲题题解-1121. Damn Single (25)-水题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789787.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  9. 第一次Sprint冲刺结果评价

    组名 软件项目名称 评价 hzsy 图文转换        这款软件最初的目标是扫描书本上文字转换成电子版,而且也可以将语音转换成文字,但在展示时,没有实现完整的功能,只有简单的界面,看不到更深的实质 ...

  10. Book Review 《构建之法》-2

    -敏捷流程包括了几大原则:Backlog.burn-down.Sprint.Scrum. 敏捷开发注重个人之间的交流,提倡尽早的交付有价值的软件满足顾客的需求, 在开发过程中不断与客户进行交互,变化. ...