希尔排序
希尔排序(Shell Sort)就是将原本有大量记录数的记录进行分组(将相距某个“增量”的记录组成一个子序列),此时每个子序列待排序的记录个数就比较少了,然后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时,再对全体记录进行一次直接插入排序。
所谓基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间,像{2, 1, 3, 6, 4, 7, 5, 8, 9}这样可以称为基本有序了。但像{1, 5, 9, 3, 7, 8, 2, 4, 6}这样9在第三位,2在倒数第三位就谈不上基本有序了。
核心代码
1 void ShellSort(int arr[], int len)
2 {
3 int j;
4 int k;
5 int nGap;
6 int temp;
7
8 assert(arr!=NULL && len>0);
9
10 //定步长
11 for(nGap=len/2; nGap>0; nGap/=2)
12 {
13 //根据步长进行分组
14 //各组内进行插入排序
15 for(j=nGap; j<len; ++j)
16 {
17 //有序数组的最后一个
18 k = j-nGap;
19 //无序数组的第一个
20 temp = arr[j];
21
22 while(temp<arr[k] && k >= 0)
23 {
24 arr[k+nGap] = arr[k];
25 k -= nGap;
26 }
27
28 arr[k+nGap] = temp;
29 }
30 }
31 }
算法分析:
最好时间复杂度:O(n) 有序
平均时间复杂度:O(n^1.5)
最坏时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
对于希尔排序,增量的选取是关键,但是这目前还是一个数学难题,不过大量的研究表明,当增量序列为dlta[k] = 2^(t-k+1)-1(0≤k≤log2(n+1)向下取整)时,可以获得不错的效果。注意:增量序列的最后一个增量必须等于1才行。