希尔排序(Shell’s Sort)顾名思义,是一个叫Shell的人发明的算法。希尔排序又称为”缩小增量排序”,是针对直接插入的一种极端情况的优化。
直接插入排序的时间复杂度是O(n²),但是如果待排序列有序的话,插入排序的时间复杂度可以达到O(n),所以如果待排序列是接近有序的话,那么直接插入的效率就可以大大提到了。
希尔排序的基本思想是将待排序列分成若干个子序列,分别对其采用直接插入,等待排序列基本有序时,在对全体记录进行一次直接插入排序。
因为采用了分组排序的思想,所以每个关键字都是在和同一子序列的前一个记录的关键字进行比较。这样关键字较小的记录就不是一步一步地往前挪动,而是”跳跃式”地往前移动。
当最后一次进行增量为1的排序时,因为整个序列已经是接近有序了,所以只需进行少量移动即可。时间复杂度较之直接插入是降低了。
下来看一下代码实现:
void ShellSort(int* array,int size)
{
int gap = size;//gap就是增量
while(gap > 1)
{
gap = gap/3+1;//加1是保证最后一次肯定是增量为1的排序
for(int i = 0;i < size -gap;++i)
{
int end = i;
int tmp = array[end + gap];
while(end >= 0)
{
if(array[end] > tmp)
array[end + gap] = array[end];
else
break;
end -=gap;
}
array[end + gap] = tmp;
}
}
}
至于希尔排序的时间复杂度,由于它的时间是所取”增量”,所以不能直接计算其时间复杂度。
有人做过研究,希尔排序的时间复杂度为O(n1.6)这里是次方。
并且gap的取值每次缩减为1/3。