数据结构:希尔排序

Posted

tags:

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

参考技术A

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

说说我的个人理解:

希尔排序其实就是直接插入排序的升级,原理就是先将整个待排序列按照某个增量(也称步长)分割成若干个子序列分别进行直接插入排序,然后合并,之后依次缩小增量大小在进行排序,当增量足够小(通常为1)时,再对全体元素进行直接插入排序,而此时需排序的数据几乎是已排好的了,所以此时插入排序较快。

当然如果你觉得文字比较乏味就看下面的这些例子吧

例如,假设有这样一组数 [9 1 5 8 3 7 4 6 2] ,如果我们先以步长为4进行分割,就是这样:

然后我们对每列进行排序(注意每列哦):

将上述四行数字,依序合并我们得到: [ 2 1 4 6 3 7 5 8 9 ] 。此时2已经往前移,而8、9已经在后两位,然后再以2为步长进行分割:

继续排序:

合并得到 [ 2 1 3 6 4 7 5 8 9] ,此时序列已经基本有序,需交换数据的情况大为减少,这时整列进行直接插入排序效率就非常高。

最终完成排序过程,也就是步长为1时,得到最终序列为: 1 2 3 4 5 6 7 8 9 。

可能有几个步骤略难懂,这里解释下:

当 时,9和3进行了一次交换,变为 (3 9 2) (位置为1 5 9),之后在 时 ,做出的交换如上图所示(图略差...),分为三个步骤:

步长的选取非常关键,但是步长的选择没有统一规定,也没绝对的规律。只要满足最后一个步长为1即可。Donald Shell最初建议步长选择为 ,虽然这样去可以比 类的算法更好,但仍然有减少平均时间和最差时间的余地。维基百科给出的部分步长与最坏情况下复杂度有:

已知的最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,...),该序列的项来自 和 这两个算式。这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序要快,甚至在小数组中比快速排序和堆排序(后续博客整理),但是在涉及大量数据时希尔排序还是比快速排序慢。

数据结构|希尔排序


介绍

最坏时间复杂度O(n^2)

希尔排序是插入排序的一种,是直接插入排序算法的一种更高效的改进版。(学习希尔排序之前需要了解插入排序)。

插入排序是每次向右移动一个步长的距离,对当前数值进行操作。而希尔排序就是加大插入排序的步长,这样可以使得元素可以一次性的朝最终位置前进一大步。

举例

给出一个无序列表(下图),假设希尔排序的gap(间隔/步长)为4,可以得到四个子序列,下标为0、4、8的序列1,下标为1、5的序列2,下标为2、6的序列3、下标为3、7的序列4。

之后对每个子序列进行插入排序

如对序列1进行插入排序,将78与53比较,再将21先78做比较、再与53做比较,得到排序后的序列:21、53、78。

对所有子序列进行插入排序后再重组得到下图

数据结构|希尔排序

之后将步长缩小为2,重复上述操作,当步长为1时的操作结束后停止,就可以得到一个有序序列。

数据结构|希尔排序

问题解答

可能很多人刚开始接触时,会觉得这样会使插入算法变得更复杂,好像执行的步骤增加了。不是这样,虽然希尔排序的最坏时间复杂度与插入算法相同,但希尔排序的最优时间复杂度是根据步长序列的不同而不同的,最好的情况下,时间复杂度可以降到O(n^1.3)。

那这个步长怎么取呢?这个难题至今没有解答,但经过大量的实验,人们还是积累了一定的经验。

在希尔的原稿中建议的初始步长是N/2,就是是将每一次排序分成两半,虽然这样取步长在大多数情况下仍然比插入排序好,但也算不上较好,网上可以搜出很多取法,感兴趣的可以搜来看看。这里我们就以希尔原稿中的步长来讲解。

代码实现

数据结构|希尔排序

灰线左边是不需要移动的值,右边的值需要与左边作比较,因此每次循环都需要将右边的值与左边作比较。操作顺序:78、30、43、56、21。


78的下标是4也就是步长gap,那30的下标是gap+1,43是gap+2,56是gap+3,21是gap+4。

还记得上文说的,希尔算法其实就是插入算法的改进嘛,所以我们从插入算法入手。从内往外,先写每次需要执行的比较代码。

    1.先将一个子序列的灰线右边与左边做比较

数据结构|希尔排序

    2.每个子序列执行的操作相同,用一个循环控制不同序列的内部比较

数据结构|希尔排序

    3.此时一个步长所要执行的操作已结束,再用一个循环控制不同步长的操作





END


主  编   |   张祯悦

责  编   |   马原涛


 where2go 团队


   

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!


以上是关于数据结构:希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

数据结构排序---希尔排序

Java数据结构之排序---希尔排序

[数据结构]希尔排序

吴裕雄--天生自然数据结构:十大经典排序算法——希尔排序

数据结构|希尔排序

数据结构和算法-排序算法-希尔排序