//希爾排序
#include<stdio.h>
#define MAX_SIZE 20
#define N 10
#define T 3
struct RedType // 記錄的類型
{
int key;
int others;
};
struct SqList //順序表的類型
{
RedType r[MAX_SIZE+1]; //r[0]閒置或者用作哨兵單元
int length;//順序表的長度
};
<span style="color:#ff0000;">//注意下面的這個函數只是進行一趟希爾排序
</span><span style="color:#ff0000;">//對順序表L作一趟希爾插入排序,本算法和直接插入排序做了以下的修改:
//前後記錄位置的增量不是1而是dk
//r[0]只是暫存單元,不是哨兵
</span>void ShellInsert(SqList &L,int dk)
{
int i,j;
for(i=1+dk;i<=L.length;i++) //注意這裏是i++不是i+=dk,因爲從開始的每一個元素都要向後查找dk
{
if(L.r[i].key < L.r[i-dk].key) //需要將r[i]插入有序增量子表
{
L.r[0] = L.r[i];//暫時存放在L.r[0]
//記錄後移,查找插入的位置
for(j=i-dk;j>0 && L.r[0].key < L.r[j].key;j-=dk)
{
L.r[j+dk]=L.r[j];
}
L.r[j+dk]=L.r[0];//插入
}
}
}
//打印每一趟的排序的結果
void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
{
printf("%d ",L.r[i].key);
}
printf("\n");
}
//打印最後的排序的結果
void print1(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
{
printf("(%d,%d) ",L.r[i].key,L.r[i].others);
}
printf("\n");
}
<span style="color:#ff0000;">//注意下面的這個函數是按照增量序列進行總的希爾排序
</span><span style="color:#ff0000;">//按照增量序列dlta[0..t-1]對順序表L作希爾排序
</span>void ShellSort(SqList &L,int dlta[],int t)
{
int k;
for(k=0;k<t;k++)
{
ShellInsert(L,dlta[k]);//一趟增量爲dlta[k]的插入排序
printf("第%d趟排序的結果:",k+1);
print(L);
}
}
void main()
{
int i,j;
RedType r[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8},{55,9},{4,10}};
SqList l;
<span style="color:#ff0000;">int dt[T]={5,3,1};//增量序列數組,,注意增量序列的最後一個增量爲1</span>
l.length=N;
for(i=0;i<=l.length;i++)
{
l.r[i+1]=r[i];
}
printf("排序前:");
print(l);
ShellSort(l,dt,T);
printf("排序後:\n");
print1(l);
}
(1)希爾排序的排序過程原理圖如下:
這個排序的增量序列爲dt[3]={5,3,1}; 注意最後的一個增量要爲1。你要對照着這個過程圖自己走幾遍,是不是很清晰明瞭?是不是恍然大悟?
(2)程序的運行結果如下: