先取一个正整数(分组步长)d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。
算法思想:
在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
希尔排序是不稳定的。
code1
/*
希尔排序
*/
#include <stdio.h>
#include <stdlib.h>
#define A 11
int s[A]={592,401,874,141,348,72,911,887,820,283,100};
void shellsort(int s[],int d,int n)
{
int i,j,temp;
for(i=d;i<n;i++) //从每一组的第二个元素开始插入排序
{
temp=s[i];
j=i-d;
while(j>=0 && s[j]>temp) //寻找插入位置,后移
{
s[j+d]=s[j];
j-=d;
}
s[j+d]=temp; //插入
}
return;
}
int main(void)
{
int d,i;
d=A/2; //步长
while(d>=1)
{
shellsort(s,d,A); //针对每个步长进行插入排序
d=d/2;
}
printf("The shell sort result is:\n");
for(i=0;i<A;i++)
{
printf("%d ",s[i]);
}
printf("\n");
system("pause");
return 0;
}
code2(foolish)
/*
希尔排序
*/
#include <stdio.h>
#include <stdlib.h>
#define A 11
int s[A]={592,401,874,141,348,72,911,887,820,283,100};
void shellsort(int s[],int n,int d)
{
int i,j,k;
int cnt;
int temp[A];
int num;
for(i=0;i<d;i++)
{
cnt=0;
while(cnt*d+i<n)
{
num=s[cnt*d+i];
j=0;
while(num>temp[j] && j<cnt)
{
j++;
}
if(j<cnt)
{
k=cnt;
while(k>j)
{
temp[k]=temp[k-1];
k--;
}
temp[j]=num;
cnt++;
}
else
{
temp[cnt++]=num;
}
for(k=0;k<cnt;k++)
{
s[k*d+i]=temp[k];
}
}
}
return;
}
int main(void)
{
int d;
int i;
d=A/2;
while(d>=1)
{
shellsort(s,A,d);
d=d/2;
}
printf("The shell sort result is:\n");
for(i=0;i<A;i++)
{
printf("%d ",s[i]);
}
printf("\n");
system("pause");
return 0;
}