希尔排序(shellsort)又叫增量递减(diminishing increment)排序,是由D.L. Shell发明的,这个算法是通过一个逐渐减小的增量使一个数组逐渐趋近于有序从而达到排序的目的。
希尔排序的实质就是分组插入排序,该方法又称缩小增量排序。
该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
插入排序的算法复杂度为O(n2),但如果序列为正序可提高到O(n),而且直接插入排序算法比较简单,希尔排序利用这两点得到了一种改进后的插入排序。
![](https://img-my.csdn.net/uploads/201209/06/1346931476_8161.jpg)
![](https://img-my.csdn.net/uploads/201209/06/1346931514_9288.jpg)
二. 算法分析
平均时间复杂度:希尔排序的时间复杂度和其增量序列有关系,这涉及到数学上尚未解决的难题;不过在某些序列中复杂度可以为O(n1.3);
空间复杂度:O(1)
稳定性:不稳定
以n=10的一个数组49, 38, 65, 97, 26, 13, 27, 49, 55, 4为例
第一次 gap = 10 / 2 = 5
49 38 65 97 26 13 27 49 55 4
1A 1B
2A 2B
3A 3B
4A 4B
5A 5B
1A,1B,2A,2B等为分组标记,数字相同的表示在同一组,大写字母表示是该组的第几个元素,每次对同一组的数据进行直接插入排序。即分成了五组(49, 13) (38, 27) (65, 49) (97, 55) (26, 4)这样每组排序后就变成了(13, 49) (27, 38) (49, 65) (55, 97) (4, 26),下同。
第二次 gap = 5 / 2 = 2
排序后
13 27 49 55 4 49 38 65 97 26
1A 1B 1C 1D 1E
2A 2B 2C 2D 2E
第三次 gap = 2 / 2 = 1
4 26 13 27 38 49 49 55 97 65
1A 1B 1C 1D 1E 1F 1G 1H 1I 1J
第四次 gap = 1 / 2 = 0 排序完成得到数组:
4 13 26 27 38 49 49 55 65 97//希尔排序
void shellSort(int a[], int n) {
int d, i, j, temp;
d = n/2; //分成n/2组
while (d >= 1) {
for (i = d; i < n; ++i) { //对每组进行直接插入排序
temp = a[i];
for (j=i-d;j>=0&&a[j]>temp;j-=d)
{
a[j+d] = a[j];
}
a[j+d] = temp;
}
d /= 2;
}
}