接上文。增量序列h有两条重要性质:
首先,定义h排序结束后的数组为h有序。
1、k排序一个h有序的数组,得到的数组既为k有序也为h有序。
2、当k、h互质时,对该新数组进行g排序,比较次数少于N(k?1)(h?1)/g
下面是一个很不错的增量序列hi=1,8,23,77,281,1073,4193,16577...,经实验发现,它的表现好于hn=3hn?1+1与hn=2hn?1+1。有文献证明,该序列的希尔排序复杂度下界为O(N4/3)。
更进一步,根据性质2,假如一个2有序且3有序的数组进行最后一遍排序(1排序),比较次数为线性。
1971年,pratt提出了一个增量三角形:
该图中每个数都是左上数的三倍,右上数的两倍。实际应用中,可以将{2,3}替换成较大的互质素数对{h,k},以减少序列项的数量。
以下是N=20000时的一组完全随机实验数据:
hn=2hn?1+1
8191 4095 2047 1023 511 255 127 63 31 15 7 3 1
shell sort step 321464
hn=3hn?1+1
9841 3280 1093 364 121 40 13 4 1
shell sort step 387480
hn=2hn?1
8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1
shell sort step 1684506
hi=1,8,23,77,281,1073,4193,16577...
16577 4193 1073 281 77 23 8 1
shell sort step 373642
对该数列进行增项训练,发现在1073和281之间插入一项541,能得到较好结果:
16577 4193 1073 541 281 77 23 8 1
shell sort step 318192
同理,对hn=3hn?1+1研究后发现,将第二项13替换为23,得到结果为局部最优。
9841 3280 1093 364 121 40 23 4 1
shell sort step 342600
由此想到如下改进:
首先固定h0,h2,h3,...,枚举h1,得到最优数列。
接着固定h0,h1,h3,...,枚举h2,得到最优数列。
依次类推,最后得到一个新的数列hi^。
hi=1,5,23,65,175,383,969,2171,4626,9251...
4626 2171 969 383 175 65 23 5 1
shell sort step 269223
best step = 269223, val = 9251
此时,较原增量数列,已提高43%效率。
版权声明:本文为博主原创文章,未经博主允许不得转载。