对于排序这项程序,看似复杂度很难缩小,但希尔却以其奇妙的想法发明出了希尔排序算法。
首先我们要理解希尔排序分为:
1.预排序(使数组变为接近有序) 预排序实际使就是分n个组实现各组的排序,这里我们用gap来表示一个组内相邻的成员之间的下标差,仔细想一下实际上gap不就是组数吗?
2.直接插入排序
我们先来看一个预排序的简单代码:
上图就实现了一组预排序,但是一组一组排的,复杂度有点高
我们可以实现多组并排
对于预排序来说我们要知道:
gap值越大,大的值更快调到后面,小的值可以更快的调到前面,越不接近有序
gap值越小,调的越慢,但是越接近有序,如果gap==1,这时就是选择排序了
那就出现一个问题了,gap值应该给多少呢,如果固定的值,那数据的大小不同,肯定不是所有都适用,所以这个gap的值是和n的值有某种关系的,也就是实现完一组预排序后得到的结果依然不是很有序,我们要再进行一次预排序,那这时我们的预排序的gap就必须发生变化,那又怎么变呢?这个问题到现在依然没有一个公认的最好的方法,但所有使用的方法都满足最后一次gap必须为1,这样才能最后一次直接排序搞定,希尔本人是让gap==n;每次预排序后gap/2,当gap的值>1时再次进行循环,直至gap==1,完成最后一次直接排序;但是后人却发现似乎这样不是最好的,也是初始化gap==n,每次循环即进行一次预排序后,gap=gap/3+1;这样来完成排序,总之,两种方法都可以,但我觉得第二种方法比较好,(只是觉得)。
我们可以容易算出预排序的次数,以第二种方法为例,其时间复杂度为0(log3N),但时每一次预排序的时间复杂度是多少呢?由于其跟gap的值有很大的关系,所以以小编的能力来算出其表达式有点难度,当gap值非常大时,其复杂度为0(N),通过翻阅大量资料我发现其的复杂度大致可以有以下规律:
这些知识只要大家了解就行,另外,有一本著名文献上将其时间复杂度大致为0(N^1.3)