2.希尔排序
希尔排序,也叫做减小增量排序,过程大致如下:(一般情况下,我们习惯上第一次遍历将数组长度length/2 作为一次遍历的步长)
以数组a[] = {35, 27, 17, 22, 5, 25, 18, 40, 9, 11}为例;
1.取数组长度(length/2)作为第一次遍历的步长,对每一组进行直接插入排序:
2.取上一次步长的一半 ,即 5/2 = 2为步长,将每一组进行直接插入排序:
3.取上一次步长的一半,即2/2 = 1为步长,进行一次直接插入排序;
这三步执行完毕后,数组已经按照从小到大排序了,那么有人会有疑惑,既然希尔排序的最后一次遍历就是对整个数组进行直接插入排序,那我们为什么还要用希尔排序呢?
有耐心的同学可以自己写一个乱序的数组,然后对它分别进行希尔排序和直接插入排序的步骤分解,会发现希尔排序执行的次数要少于直接插入排序,就是说希尔排序的效率高于直接插入排序。
下面附上代码:
#include <stdio.h>
void ShellSort(int arr[], int len)
{
int i, j, tmp, gap;
for(gap = len / 2 ; gap > 0; gap /= 2)
{
for(i = gap; i < len; i++)
{
tmp = arr[i];
for(j = i - gap; j >= 0 && arr[j] > tmp; j -= gap)
{
arr[j+gap] = arr[j];
}
arr[j+gap] = tmp;
}
}
}
int main()
{
int i, length;
int a[] = {35, 27, 17, 22, 5, 25, 18, 40, 9, 11};
length = sizeof(a) / sizeof(a[0]);
ShellSort(a, length);
for(i = 0; i < length ; i++)
{
printf("%d ", a[i]);
}
return 0;
}
看完代码,熟悉直接插入排序的同学,可以发现希尔排序就是在直接插入排序外部插入了一层循环,用来控制步长。