目录
一. 前言
插入排序找到插入位置一共有三种方法,分别是直接插入排序,二分插入排序以及希尔排序。
希尔排序的基本思想:先将整个待排记录分割成若干个子序列,分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。它一种通过缩小增量,多遍插入排序来达到目的的算法。
二. 希尔算法的实现
首先给出一组初始数据,然后通过增量间隔,每隔一个间隔的元素为一组,进行直接插入排序,然后缩小这个增量间隔,再分组进行直接插入排序;最后一步就是间隔为1的排序,到这里整个希尔排序也就结束了。如下所示:
首先增量间隔为5,所以蓝色图标的数据为一组,粉色图标的为一组等等。
通过上述分析,可得出希尔排序的特点:
1)它每一次移动的位置都比较大。
2)最后一次只需要少量移动。
3)增量序列必须是递减的,最后一个必须是1。
4)增量序列应该是互质的。
希尔排序代码实现如下所示:
void ShellSort(SqList&L, int dlta[],int t){ //dlta[]为一个存放增量的数组,t为里面增量的数量
for(k=0;k<t;k++){
ShellInsert(L,dlta[k]); //每换一次增量就重新进行一遍
}
void ShellInsert(SqList&L,int dk){
for(int i=dk+1;i<=L.length;i++)
if(r[i].key<r[i-dk].key){ //如果当前元素小于它前面间隔为dk的元素
r[0]=r[i]; //临时存放到0号位置
for(int j=i-dk;j>0&&(r[0].key<r[j].key;j=j-dk)
r[j+dk]=r[j]; //移动元素,大于这个元素的往后移,每次移动dk个位置
r[j+dk]=r[0]; //将临时位置的值取出来放到这个正确的位置
}
}
希尔排序是一种不稳定的排序方法。关于如何选择最佳的增量dk序列,目前尚未解决。但希尔排序最后一个增量值必须是1,并且它不适宜在链式存储结构上实现,因为链式存储结构并不是一个连续完整的存储单元。