基本思想:
简单插入排序的改进。先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
步骤:
- 定义增量序列Dk:Dm>Dm-1>...>D1=1
- 对每个Dk进行“Dk-间隔”的插入排序(k=M,M-1,...1)
特点:
1.一次移动,移动位置较大,跳跃式地接近排序后的最终位置
2.最后一次只需要少量移动
3.增量序列必须是递减的,最后一个必须是1
4.增量序列应该是互质的,无除1外的公因子
5.不宜在链式存储结构上实现
void ShellInsert(SqList &L,int dk){
for(i=dk+1;i<=L.length;i++){
if(r[i].key<r[i-dk].key){
r[0]=r[i];
for(j=i-dk;j>0&&(r[0].key<r[j].key);j=j-dk)
r[j+dk]=r[j];
r[j+dk]=r[0];
}
}
}
void ShellSort(Sqlist &L,int dlta[],int t){ //dlta是存放增量序列的数组,t是数组大小
for(k=0;k<t;k++)
ShellInsert(L,dlta[k]);
}
时间复杂度分析:
希尔排序是不稳定排序,其算法效率与增量序列的取值有关。
目前尚未有一个最好的取增量序列的办法,原始希尔排序的取法是Dm=待排序列长度/2,第i个增量Di=Di+1/2。
Hibbard增量序列的取法:Dk=-1
其猜想最坏情况:O()/O(
)
猜想平均情况:O()/O(
)