一、简介:希尔排序是对插入排序进行优化得来的一种排序方法,插入排序有两个缺陷影响其效率,一是、排序时间主要消耗在查找插入位置和移动上,当序列特别无序时,耗时 增多二是、当序列数目特别大时,效率降低。优化后,先将序列分拆后进行插入排序,让序列基本有序后,在进行一趟插入排序。
一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size
而不是i++
)。
例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:
13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10
然后我们对每列进行排序:
10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45
將上述四行數字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:
10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45
排序之后变为:
10 14 13 25 23 33 27 25 59 39 65 73 45 94 82 94
最后以1步长进行排序(此时就是简单的插入排序了)。
二、C语言实现:函数ShellSort 实现希尔排序
#include<stdio.h> #include<stdlib.h> #include<time.h> #define NUM 5 void ShellSort(int *l,int length); int main() { int i,a[NUM+1]; srand((unsigned)time(NULL)); /*a[0]作为哨兵单元,不在随机数生成之列*/ for(i=1;i<=NUM;i++) { a[i]=rand(); } /*printf("Befor sort:"); for(i=1;i<=NUM;i++) { printf("%d ",a[i]); }*/ ShellSort(a,NUM); printf(" After sort:"); for(i=1;i<=NUM;i++) { printf("%d ",a[i]); } return 0; } void ShellSort(int *l,int lenght) { int i,j,dlta; dlta=lenght; while(dlta>1) { dlta=dlta/3+1; //步长计算 for(i=1+dlta;i<=lenght;i++) //下面的循环就是对间隔为dlta的序列元素进行插入排序,直到dlta=1 { if(l[i]<l[i-dlta]) { l[0]=l[i]; for(j=i-dlta;j>0&&l[0]<l[j];j-=dlta) l[j+dlta]=l[j]; l[j+dlta]=l[0]; } } } }