基本思想:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
我们先来看一下算法(大话数据结构一书中如上节所述,存在一些小问题,我们稍作修改即可)
void ShellSort0(SqList* L)
{
int i = 0,j = 0,temp = 0;
int increment = L->iLength;
do
{
increment = increment/3+1; //截取增量
for (i=increment;iiLength;i++) //此处当increment=1时为直接插入排序
{
if (L->iElem[i]iElem[i-increment])
{
temp = L->iElem[i];
for (j=i-increment;j>=0 && L->iElem[j]>temp;j-=increment)
{
L->iElem[j+increment] = L->iElem[j];
}
L->iElem[j+increment] = temp;
PrintList(*L);
}
}
} while (increment>1);
}
从上述算法我们可以看出上述希尔排序其实就是根据增量进行直接插入排序,为此,我们将上一节当中的直接插入排序,提取增量变量作为函数参数,代码如下:
//当增量为dk为1时,代表直接插入排序
void InsertSort_Up_Dk(SqList* L,int dk) //升序,按增量
{
int i = 0,j = 0,temp = 0;
for (i=dk;iiLength;i++)//循环从第二个元素开始
{
if (L->iElem[i] < L->iElem[i-dk])
{
temp = L->iElem[i];//设置哨兵
for (j=i-dk;j>=0 && L->iElem[j]>temp;j-=dk)//将哨兵前的元素与哨兵进行比较,如果比哨兵元素大,则将元素进行后移
{
L->iElem[j+dk] = L->iElem[j]; //记录后移
}
L->iElem[j+dk] = temp; //插入到正确位置
}
}
}
然后,我们根据增量的设定来进行函数调用,就可以演变成希尔排序算法,具体如下:
void ShellSort(SqList *L)
{
int idk = L->iLength/2;
while( idk >= 1 ){
InsertSort_Up_Dk(L, idk);
cout<<"swap at dk= "<
我们将完整的代码编译运行如下所示:
#include
#include
using namespace std;
#define MAX_SIZE 5
typedef struct
{
int iElem[MAX_SIZE];
int iLength;
}SqList;
void PrintList(SqList L)
{
for (int i=0;iiLength = 0;
srand((unsigned)time(NULL));
int iData[MAX_SIZE]={19,4,84,38,26};
for (i=0; iiElem[i] = rand()%100;
L->iElem[i] = iData[i];
L->iLength++;
}
PrintList(*L);
}
void InsertSort_Up(SqList* L) //升序
{
int i = 0,j = 0,temp = 0;
for (i=1;iiLength;i++)//循环从第二个元素开始
{
if (L->iElem[i] < L->iElem[i-1])
{
temp = L->iElem[i];//设置哨兵
for (j=i-1;j>=0 && L->iElem[j]>temp;j--)//将哨兵前的元素与哨兵进行比较,如果比哨兵元素大,则将元素进行后移
{
L->iElem[j+1] = L->iElem[j]; //记录后移
}
L->iElem[j+1] = temp; //插入到正确位置
cout<<"swap at i= "<iLength;i++)//循环从第二个元素开始
{
if (L->iElem[i] < L->iElem[i-dk])
{
temp = L->iElem[i];//设置哨兵
for (j=i-dk;j>=0 && L->iElem[j]>temp;j-=dk)//将哨兵前的元素与哨兵进行比较,如果比哨兵元素大,则将元素进行后移
{
L->iElem[j+dk] = L->iElem[j]; //记录后移
}
L->iElem[j+dk] = temp; //插入到正确位置
}
}
}
void ShellSort(SqList *L)
{
int idk = L->iLength/2;
while( idk >= 1 ){
InsertSort_Up_Dk(L, idk);
cout<<"swap at dk= "<
运行结果: