希尔排序(Shell's Sort)是插入排序的一种又称"缩小增量排序"(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。 希尔排序是非稳定排序算法。 该方法因D.L.Shell 于1959 年提出而得名。
希尔排序有点类似插入排序,可以说是插入排序的改进版,其思想很简单,如下:
下附详解图。
1.先对需要排序数据进行分组,因为是两两交换所以一共分为N/2组。然后进行两两对比,如果前面这个数字比后面的数字大就交换位置。
以数组 5 2 10 4 7 1 3 8 6 9 为例,数组长度为10,及在这一步一共分为5组。对比间隔为5,然后5->1,2->3,10->8,4->6,7->9 进行比较然后相应的交换位置。然后这一轮后数组变为1 2 8 4 7 5 3 10 6 9
2.现在进行第二趟排序,5/2=2,现在对比间隔为2,一共分为5组,则1->8,2->4 .... 依次类推。然后这一轮数组变为1 2 7 4 3 5 6 9 8 10
3.现在进行第三轮,2/2=1,现在对比间隔为1,一共分为10组,则 1->2,2->7 ...... 依次类推。这一轮比完后就排好了。
总之这个算法就是从数组长度确定的对比间隔,然后每一轮除2一直除到为1这一轮就排好了。
下面是详细图,只有第一轮和第二轮。
代码
#include <stdio.h>
#include <malloc.h>
void shellSort(int *a, int len);
int main(void)
{
int i, len, * a;
printf("请输入要排序的数的个数:");
scanf("%d",&len);
a = (int *)malloc(len * sizeof(int));
printf("请输入要排序的数:\n");
for (i = 0; i < len; i++)
{
scanf("%d",&a[i]);
}
shellSort(a, len);
printf("希尔排列后为(升序):\n");
for (i = 0; i < len; i++)
{
printf("%d ",a[i]);
}
free(a);
printf("\n");
return 0;
}
void shellSort(int *a, int len)
{
int i, j, k, tmp, gap; // gap 为步长
for (gap = len / 2; gap > 0; gap /= 2)
{
for (i = 0; i < gap; ++i)
{
for (j = i + gap; j < len; j += gap)
{
tmp = a[j];
k = j - gap;
while (k >= 0 && a[k] > tmp)
{
a[k + gap] = a[k];
k -= gap;
}
a[k + gap] = tmp;
}
}
}
}