希尔排序属于插入排序的一种,每次设定一个步长dk,则把原数组分为dk个分数组:
A1[0,dk,2dk,3dk,4dk,...].
A2[1,dk+1,2dk+1,3dk+1,4dk+1,...]
A3[2,dk+2,2dk+2,3dk+2,4dk+2,...]
。。。。。。
每个分数组分别进行直接插入排序。
然后将dk的值逐渐减小,再进行如上排序。直到减小到1时,原数组最后进行的就是一次直接插入排序。这样数组就排好序了。
dk的初始值一般为原数组A的长度len的一半,为dk=len/2;
dk的结尾值为1;每一次dk/=2; 呈指数型减小。
问题:
为何要进行dk>1时的哪些排序?直接dk=1,直接插入排序不就完事了吗。
答:
插入排序的时间复杂度是与数组的状态有关的。进行了dk>1的那些排序后,会大大减小dk=1时的排序。当n处于某个特定范围内时,希尔排序的时间复杂度为O(n^1.3).在最坏情况下,希尔排序的时间复杂度为O(n*n).
void ShellSort(int A[], int n){
int dk;
for(dk=n/2;dk>=1;dk/=2){//dk在呈指数性减小。
for(int i=dk;i<n;i++){
if(A[i]<A[i-dk]){
int temp=A[i];
int j;
for(j=i-dk;j>=0;j-=dk){
if(temp<A[j])
A[j+dk]=A[j];
else
break;
}
A[j+dk]=temp;
}
}
}
}