希尔排序
@Author: 张海拔
@Update: 2014-01-11
@Link: http://www.cnblogs.com/zhanghaiba/p/3513509.html
1 /* 2 *Author: ZhangHaiba 3 *Date:2014-1-10 4 *File: shell_sort.c 5 * 6 *a shell sort demo 7 */ 8 9 #include <stdio.h> 10 #define N 512; 11 12 //public 13 void shell_sort(int*, int); 14 void shell_sort2(int*, int); 15 void set_array(int*, int); 16 void show_array(int*, int); 17 //private 18 void swap(int*, int*); 19 20 int array[512]; 21 22 int main(void) 23 { 24 int n; 25 26 scanf("%d", &n); 27 set_array(array, n); 28 shell_sort(array, n); 29 show_array(array, n); 30 return 0; 31 } 32 33 void shell_sort(int *a, int n) 34 { 35 int gap, i, j, key; 36 37 for (gap = n/2; gap > 0; gap /= 2) 38 for (i = 0; i < n; ++i) { 39 key = a[i]; 40 for (j = i-gap; j >= 0 && a[j] > key; j -= gap) 41 a[j+gap] = a[j]; 42 a[j+gap] = key; 43 } 44 } 45 46 void shell_sort2(int *a, int n) 47 { 48 int gap, i, j; 49 50 for (gap = n/2; gap > 0; gap /= 2) 51 for (i = 0; i < n; ++i) 52 for (j = i-gap; j >= 0 && a[j] > a[j+gap]; j -= gap) 53 swap(&a[j], &a[j+gap]); 54 } 55 56 void set_array(int *a, int n) 57 { 58 int i; 59 60 for (i = 0; i < n; ++i) 61 scanf("%d", a+i); 62 } 63 64 void show_array(int *a, int n) 65 { 66 int i; 67 68 for (i = 0; i < n; ++i) 69 printf(i == n-1 ? "%d\n" : "%d ", a[i]); 70 } 71 72 void swap(int *a, int *b) 73 { 74 int tmp = *a; 75 *a = *b; 76 *b = tmp; 77 }
希尔排序是基于直接插入排序的改进
首先你要理解直接插入排序,因为当gap == 1时(外层循环最后一次),此时做的就是赤裸裸的直接插入排序。
数组“基本有序”时,直接插入排序的效率接近O(n);而数组是随机情况,直接插入排序的效率接近O(n^2)。
希尔排序就是利用上述两个特征来提高效率的——
由于n^2是二次函数增长的。n很小和n很大时,函数变化率差别很大。因此通过初始一个n/2的增量,使真正进行插入排序的数组(物理不连续但逻辑连续的数组,因为隔空了)规模很小,此时效率接近O(n^2),但对整个规模的排序效率来说影响并不大。
其次,随着增量变小,数组却变得“基本有序”了,此时哪怕真正进行插入排序的数组(隔空的数组)规模比较大了,但效率会比较紧接O(n)。