希尔排序又称缩小增量排序,是对插入排序的优化.
举例来说明希尔排序:
假设初始数据为
9 1 2 5 7 4 8 6 3 5 共10个数据
取 gap = n / 2 即 gap = 10 / 2 = 5
现在来看第一趟排序
具体的分组我们可以这样去看,数组中的数据下标为0 - 9.
gap = 5.将原数据分为5组数据.
这也就是说
下标0与下标0 + 5一组,即上图中的9 与 4, 9 > 4交换
下标1与下标1 + 5一组,即上图中的1 与 8, 1 < 8不交换
下标2与下标2 + 5一组,即上图中的2 与 6, 2< 6不交换
下标3与下标3 + 5一组,即上图中的5 与 3, 5 > 3交换
下标4与下标4 + 5一组,即上图中的7 与 5, 7 > 5交换
上述的两两交换即可看为一个插入排序的过程两个数字,第一个为记住,后面每出现一个较大的就将它插入到基准数字之前.
接下来看第二次排序
gap = gap / 2. 即 gap = 5 / 2 = 2
将经过第一次排序后的数组分为两组
4 2 5 8 5
1 3 9 6 7
分别进行插入排序
即变为
2 4 5 5 8
1 3 6 7 9
也就是上图中的
2 1 4 3 5 6 5 7 8 9
再进行第三次排序
gap = gap / 2. 即 gap = 2 / 2 = 1
将经过第二次排序后的数组分为一组,即
2 1 4 3 5 6 5 7 8 9
进行插入排序后变为
1 2 3 4 5 5 6 7 8 9
排序结束
不难看出,希尔排序确实是对直接插入排序的优化.
当gap < 1时都相当于是预排序,主要的目的是为了让数组更接近于有序.所以当gao == 1时,数据已经接近于有序了,这样利用插入排序就会很快,这样整体来看,确实可以达到优化的效果
希尔排序的稳定性是不稳定.
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUFSIZE 10000
void printArray(int* src, int n){
int i;
for (i = 0; i < n; ++i){
printf("%d ", src[i]);
}
putchar('\n');
}
//希尔排序
void shellSort(int* src, int n){
int i, j, k;
int gap;
int tmp;
for (gap = n / 2; gap; gap /= 2){
for (k = 0; k < gap; ++k){
//插入排序
for (i = gap + k; i < n; i += gap){
tmp = src[i];
for (j = i; j >= gap && src[j - gap] > tmp; j -= gap){
src[j] = src[j - gap];
}
src[j] = tmp;
}
}
}
}
int main(){
#if 0
//int src[10] = { 3, 1, 6, 7, 9, 2, 4, 8, 10, 5 };
int src[11] = { 1, 3, 6, 7, 9, 2, 4, 8, 10, 5, 11 };
ShellSort(src, 10);
printArray(src, 11);
#else
srand((unsigned int)time(NULL));
int src[BUFSIZE];
int i;
for (i = 0; i < BUFSIZE; ++i){
src[i] = rand() % 5000 + 1;
}
ShellSort(src, BUFSIZE);
printArray(src, BUFSIZE);
#endif
system("pause");
return 0;
}