决胜经典算法之希尔排序

Posted 前端开发实用技巧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了决胜经典算法之希尔排序相关的知识,希望对你有一定的参考价值。

习题答案

题目回顾

在上一篇文章中,我们以数列从小到大排列为例,讲了插入排序。结尾处的思考题如下:

如果要实现从大到小排列,上述代码该做如何修改呢?

同样,要解答这个问题也很简单,下面放上答案。

答案

我们知道,从小到大排序时,实际上就是逐个比较大小,把更小的元素向前移。同时,把整个数组分为“已排序”和“未排序”两个区域。要解决从大到小排序时,具体做法类似,只需将更大的元素向前移即可。参考如下代码:

 
   
   
 
public static void insertSort(int[] arr) { int temp; int j; for (int i = 1; i < arr.length; i++) { for (j = i - 1; j >= 0; j--) { if (arr[i] < arr[j]) break; } if (j != i - 1) { temp = arr[i]; for (int k = i; k > j + 1; k--) { arr[k] = arr[k - 1]; } arr[j + 1] = temp; } }}

怎么样,你答对了吗?


本篇文章的内容是讲第四种排序方法——希尔排序。
还是之前的问题:

问题挑战

现有如下数字:   
3,44,38,5,47,15,36,26,27,2,46,4,19,50,48   
一共15个数字,请将其从小到大依次排列。

算法解析

希尔排序,又被称为缩小增量排序。它和插入排序有相同之处,也有所区别——希尔排序会优先比较距离较远的元素。
概括地讲,希尔排序就是先取一个正整数,这个正整数暂定为3。把所有序号相隔这个数值的数组元素放一组,组内进行直接插入排序;然后再把这个正整数做自减一运算,重复上述分组和排序操作;直至这个正整数的值为1,即所有记录放进一个组中排序为止。
为什么我们把步长(即上文中的“正整数”)初始值定为3呢?因为该排序算法最复杂的就是该步长的确定。按照自减一再排序的操作,整个排序过程只需要3次排序即可完成。
是不是觉得有点不太好理解?下面我们分步拆解:

详细步骤

下面让我们来分步骤拆解整个希尔排序:


  1. 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

  2. 按增量序列个数 k,对序列进行 k 趟排序;

  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。


希尔排序的思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行依次直接插入排序。整个流程如下图(以增量为3为例)所示:

决胜经典算法之希尔排序

伪代码

接下来,我们使用伪代码实现上述过程

 
   
   
 
input: an array a of length n with array elements numbered 0 to n − 1inc ← round(3)while inc > 0 do:for i = inc .. n − 1 do:temp ← a[i]j ← iwhile j ≥ inc and a[j − inc] > temp do:a[j] ← a[j − inc]j ← j − inca[j] ← tempinc ← round(inc--)

Java代码实现

接下来,我们使用Java编程语言实现上述算法。

 
   
   
 
public static void shellSort(int[] arr) { int gap = arr.length; while (true) { // gap 表示增量,这里以数组长度的一半为例 gap /= 2; for (int i = 0; i < gap; i++) { for (int j = i + gap; j < arr.length; j += gap) { int temp = arr[j]; int k = j - gap; while (k >= 0 && arr[k] > temp) { arr[k + gap] = arr[k]; k -= gap; } arr[k + gap] = temp; } } if (gap == 1) break; }}

思考题

1. 如果要实现从大到小排列,上述代码该做如何修改呢?

思考题答案依旧会在下篇连载中公布,大家加油哦!



规则:

  1. 只要是您贡献的文章,我们不要抽成,所有打赏收益全归您;

  2. 如果您的文章有在其他平台(CSDN、博客园等等)发布,建议您添加“阅读原文”链接,往您自己的博客导流;

  3. 在发表您的文章时,会依照微信公众平台规定的原创声明规则对原创者进行声明。同时,在文章开头或结尾会附上原创作者名及联系方式。


如有意向,请识别下方二维码找我详聊,欢迎随时打扰~

 



以上是关于决胜经典算法之希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

算法讲解Scartch经典算法4之--希尔排序算法

十大经典排序之:插入排序 |希尔排序

白话经典算法系列之三 希尔排序的实现

经典排序算法系列之插入排序和希尔排序----小白理解(python)

经典排序之希尔排序

十大经典排序算法总结(希尔排序)