先取一个小于n的步长d1,把表中的全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中,在各组中进行直接插入排序;然后取第二个步长d2<d1,重复上述的过程,知道dt=1,即所有的记录已放在同一组中,再进行直接插入排序。
增量序列一般选择d1=n/2, di+1=[di/2],并且最后一个增量等于1.
void ShellSort(ElemType A[], int n)
{
//对顺序表中做希尔插入排序,本算法与直接插入排序相比,做了如下的修改
//前后记录位置的增量式dk,不是1
//r[0]只是暂存单元,不是哨兵,当j<0时,插入位置已到
for(dk=len/2; dk>=1; dk=dk/2)//步长变化
{
for(i=dk+1; i<=n; i++)
{
if(A[i].key<A[i-dk].key)//需将A[i]插入有序增量子表
{
A[0]=A[i];//暂存在A[0]
for(j=i-dk; j>0&&A[0].key<A[j].key; j-=dk)
{
A[j+dk]=A[j];//记录后移,查找插入的位置
}
A[j+dk]=A[0];//插入
}
}
}
}
时间复杂度:o(n^2)
不稳定的排序