希尔排序

基本思想:

     先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

     该方法实质上是一种分组插入方法。

具体的算法实现

K&R C程序设计一书中给出的代码 C和C++代码

 1 void shellsort(int v[], int n)
2 {
3 int gap, i, j, temp;
4 for(gap=n/2;gap>0;gap/=2) //设定步长
5 for(i=gap;i<n;++i) //在元素间移动为止
6 for(j=i-gap; j>=0&&v[j]>v[j+gap]; j-=gap)
7       { //比较相距gap的元素,逆序互换
8 temp=v[j];
9 v[j]=v[j+gap];
10 v[j+gap]=temp;
11 }
12 }

 另一种算法是这样的。

 1  不设监视哨的算法描述
2 void ShellPass(SeqList R,int d)
3 {//希尔排序中的一趟排序,d为当前增量
4 for(i=d+1;i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区
5 if(R[i].key<R[i-d].key){
6 R[0]=R[i];j=i-d; //R[0]只是暂存单元
7 do {//查找R[i]的插入位置
8 R[j+d];=R[j]; //后移记录
9 j=j-d; //查找前一记录
10 }while(j>0&&R[0].key<R[j].key);
11 R[j+d]=R[0]; //插入R[i]到正确的位置上
12 } //endif
13 } //ShellPass
14
15 void ShellSort(SeqList R)
16 {
17 int increment=n; //增量初值,不妨设n>0
18 do {
19 increment=increment/3+1//求下一增量
20 ShellPass(R,increment); //一趟增量为increment的Shell插入排序
21 }while(increment>1)
22 } //ShellSort
23 注意:
24   当增量d=1时,ShellPass和InsertSort基本一致,只是由于没有哨兵而在内循环中增加了一个循环判定条件"j>0",以防下标越界。

  

  

 

  

  

原文地址:https://www.cnblogs.com/lazycoding/p/2169384.html