希尔排序算法_wolfboy 希尔排序算法代码

希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。

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

·插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率

·但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

历史

希尔排序按其设计者希尔(DonaldShell)的名字命名,该算法由1959年公布。一些老版本教科书和参考手册把该算法命名为Shell-Metzner,即包含MarleneMetznerNorton的名字,但是根据Metzner本人的说法,“我没有为这种算法做任何事,我的名字不应该出现在算法的名字中。”

算法实现

原始的算法实现在最坏的情况下需要进行O(n2)的比较和交换。V.Pratt的书[1]对算法进行了少量修改,可以使得性能提升至O(nlog2n)。这比最好的比较算法的O(nlogn)要差一些。

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i+=step_size 而不是i++)。

例如,假设有这样一组数[13149433822559946523452773253910],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

1314943382

2559946523

4527732539

10

然后我们对每列进行排序:

1014732523

1327943339

2559946582

45

当我们以单行来读取数据时我们得到:[10147325231327943339255994658245].这时10已经移至正确位置了,然后再以3为步长进行排序:

101473

252313

279433

392559

946582

45

排序之后变为:

101413

252333

272559

396573

459482

94

最后以1步长进行排序(此时就是简单的插入排序了)。

步长序列

步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。

DonaldShell最初建议步长选择为n/2并且对步长取半直到步长达到1。虽然这样取可以比O(n2)类的算法(插入排序)更好,但这样仍然有减少平均时间和最差时间的余地。可能希尔排序最重要的地方在于当用较小步长排序后,以前用的较大步长仍然是有序的。比如,如果一个数列以步长5进行了排序然后再以步长3进行排序,那么该数列不仅是以步长3有序,而且是以步长5有序。如果不是这样,那么算法在迭代过程中会打乱以前的顺序,那就不会以如此短的时间完成排序了。

步长序列

最坏情况下复杂度

n/2i

(n2)

2k−1

(n3/2)

2i3i

(nlog2n)

已知的最好步长序列由MarcinCiura设计(1,4,10,23,57,132,301,701,1750,…)这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序和堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。

另一个在大数组中表现优异的步长序列是(斐波那契数列除去0和1将剩余的数以黄金分割比的两倍的幂进行运算得到的数列):(1,9,34,182,836,4025,19001,90358,428481,2034035,9651787,45806244,217378076,1031612713,…)[2]

伪代码

input:anarrayaoflengthnwitharrayelementsnumbered0ton−1

inc←round(n/2)

whileinc>0do:

fori=inc..n−1do:

temp←a[i]

j←i

whilej≥incanda[j−inc]>tempdo:

a[j]←a[j−inc]

j←j−inc

a[j]←temp

inc←round(inc/2.2)

C示例代码

intmain()

{

constintn=5;

inti,j,temp;

intgap=0;

inta[]={5,4,3,2,1};

while(gap<=n)

{

gap=gap*3+1;

}

while(gap>0)

{

for(i=gap;i<n;i++)

{

j=i-gap;

temp=a[i];

while((j>=0)&&(a[j]>temp))

{

a[j+gap]=a[j];

j=j-gap;

}

a[j+gap]=temp;

}

gap=(gap-1)/3;

}

}

C++示例代码

template<typenameRandomIter,typenameCompare>

voidshell_sort(RandomIterbegin,RandomIterend,Comparecmp)

{

typedeftypenamestd::iterator_traits<RandomIter>::value_typevalue_type;

typedeftypenamestd::iterator_traits<RandomIter>::difference_typediff_t;

diff_tsize=std::distance(begin,end);

diff_tstep=size/2;

while(step>=1){

for(diff_ti=step;i<size;++i){

value_typekey=*(begin+i);

diff_tins=i;

while(ins>=step&&cmp(key,*(begin+ins-step))){

*(begin+ins)=*(begin+ins-step);

ins-=step;

}

*(begin+ins)=key;

}

if(step==2)

step=1;

else

step=static_cast<diff_t>(step/2.2);

}

}

template<typenameRandomIter>

voidshell_sort(RandomIterbegin,RandomIterend){

typedeftypenamestd::iterator_traits<RandomIter>::value_typevalue_type;

shell_sort(begin,end,std::less<value_type>());

}

在Java中的示例代码

voidshellsort(int[]a,intn)

{

inti,j,k,temp,gap;

int[]gaps={1,5,13,43,113,297,815,1989,4711,11969,27901,84801,

213331,543749,1355339,3501671,8810089,21521774,

58548857,157840433,410151271,1131376761,2147483647};

for(k=0;gaps[k]<n;k++);

while(--k>=0)

{

gap=gaps[k];

for(i=gap;i<n;i++)

{

temp=a[i];

j=i;

希尔排序算法_wolfboy 希尔排序算法代码

while(j>=gap&&a[j-gap]>temp)

{

a[j]=a[j-gap];

j=j-gap;

}

a[j]=temp;

}

}

}

  

爱华网本文地址 » http://www.aihuau.com/a/25101015/244094.html

更多阅读

曝光风流女星帕里斯-希尔顿豪放瞬间 黄子韬帕里斯希尔顿

贺:本人新浪围脖粉丝突破六万人大关:http://t.sina.com.cn/a5176600欢迎关注!文、张建雄近日,希尔顿又流出不雅照,此次她到夜店狂欢,不仅扭腰抖臀,还自摸下体,尺度非常之大。不过对于这位“超级富二代”来说,这已经是很保守的了,和她之前走光

苏丹的禁宫上19贝希尔的秘密 苏丹的禁宫下

刚走到总管房间门口,我听到从那里又传来了一声贝希尔的轻笑,接着就响起了瓦西总管的声音,“贝希尔,真是可惜啊。如果你是女人,一定比这宫里任何一个妃子都要美丽,就连玫瑰夫人也要甘拜下风呢。”瓦西的声音和平时很不一样,听起来倒更像是在

苏丹总统------巴希尔其人其事 苏丹 巴希尔

苏丹总统------巴希尔其人其事(中文最全介绍)侯福斗现任苏丹总统巴希尔,全名奥马尔·哈桑·艾哈迈德·巴希尔,他的英文名字是Omar Hassan Ahmad al-Bashir,阿拉伯语名字为:&#1593;&#1605;&#1585; &#1581;&#1587;&#1606; &#1575;&#1581;

声明:《希尔排序算法_wolfboy 希尔排序算法代码》为网友黑夜的触动分享!如侵犯到您的合法权益请联系我们删除