|
|
1.定义
希尔排序( shell sort )是 D .L.希尔( D.L.Shell )提出的“缩小增量”的排序方法。它的作法不是每次一个元素挨一个元素的比较。而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置;然后增量缩小;最后增量为 1 ,这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。
2.算法思路
①先取一个正整数 d 1 (d 1 <;n) ,把全部记录分成 d 1 个组,所有距离为 d 1 的倍数的记录看成一组,然后在各组内进行插入排序;
②然后取 d 2 ( d 2 < d 1 ) 。
③重复上述分组和排序操作;直到取 d i =1(i>=1) ,即所有记录成为一个组为止。一般选 d 1 约为 n/2 , d 2 为 d 1 /2 , d 3 为 d 2 /2 ,…, d i =1 。
【例】有一组关键字{ 76 , 81 , 60 , 22 , 98 , 33 , 12 , 79 },将其按由小到大的顺序排序。这里 n=8 ,取 d 1 =4 , d 2 =2 , d 3 =1 。排序过程如图9.2所示。

具体算法演示请点击查看 【算法演示】
3.具体算法
template<class T>
void shell(T r[],int n) //希尔排序
{ int i,j,k;
k=n/2;//k值代表前文中的增量d值
while(k>=1) //当增量k值变化到0,结束循环……
{ for(i=k+1;i<=n;i++)
{ r[0].key=r[i].key;j=i-k;
while((r[j].key>r[0].key)&&(j>=0))
{ r[j+k].key=r[j].key;j=j-k;}
r[j+k]=r[0];
}
k=k/2;
}
}
4.算法分析
当K=1时,此算法就等同于直接插入排序方法。由于前边大增量的处理,使关键字大体有序,因此最后一趟排序移动的记录少,处理速度快。
有人在大量实验基础上推出,它的时间复杂长为 O(n 1.3 ) 。如果对关键字序列 {6,7,5 1 ,2,5 2 ,8} 进行希尔排序,可以看出希尔排序是不稳定的。