希尔排序(Shell's sort)又称为“缩小增量排序”(Dimimishing Increment Sort),是由希尔在1959年提出的。希尔排序是对插入排序的一种改进。
希尔排序的基本思想是:
设定一个元素间隔增量gap,将参加排序的序列按这个间隔数gap从第1个元素开始依次分成若干个子序列。例如最开始gap=3,下面的序列可这样划分:
原序列:{3, 6, 4, 2, 11, 10}
子序列1:cmp(3, 2)
子序列2:cmp(6, 11)
子序列3:cmp(4, 10)
将序列{3, 6, 4, 2, 11, 10}划分成3个子序列。在子序列中采用其他排序方法(例如冒泡排序)。然后缩小增量gap,重新将整个序列按照新的间隔数gap进行划分,再分别对每个子序列进行排序。如此将“缩小增量gap->划分序列->将每个子序列排序”操作进行下去,直到间隔数增量gap=1为止。
由于排序时每一趟都是以不同的间隔数对子序列进行排序,因此元素的移动在子序列中是跳跃式的。间隔数gap越大,跳跃的跨度就越大。一般情况下,当增量gap缩小到1时,序列大都几乎按值有序,不需要进行较多的元素移动就能达到排序的目的。
序列{3, 6, 4, 2, 11, 10, 8, 9}
第1趟排序,gap=4:{3, 6, 4, 9, 11, 10, 8, 12}
第2趟排序,gap=2:{3, 6, 4, 9, 8, 10, 11, 12}
第3趟排序,gap=1:{3, 4, 6, 8, 9, 10, 11, 12}
希尔排序算法描述如下:
void shellsort(keytype k[], int n)
{
int i, j, gap;
gap=n;
keytype temp;
while(gap>0)
{
gap = gap/2;
for(i=1; i<=n-gap; i++)
{
j = i+gap;
if(k[i] > k[j])
{
temp = k[i];
k[i] = k[j];
k[j] = temp;
}
}
}
}
实例:
#include <stdio.h>
#include <stdlib.h>
void shellsort(int a[], int n)
{
int i,j,gap;
gap = n;
int temp;
while(gap>0)
{
gap = gap/2;
for(i=1; i<=n-gap; i++)
{
j = i+gap;
if(a[i] < a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void main
{
int i;
int a[11] = {-111,2, 5, 6, 3, 7, 8, 0, 9, 12, 1};
printf("The orginal data array is\n");
for(i = 1; i <11; i++)
{
printf("%d ",a[i]);
}
bubblesort(a, 10);
printf("\nThe result of insertion sorting for the arrray is\n");
for(i = 1; i<11; i++)
{
printf("%d ", a[i]);
}
printf("\n");
system("pause");
}