希尔排序又称“缩小增量排序”。
它的基本思想是:先将整个待排记录序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录”基本有序”时,(当增量为1时)再对记录进行一次直接插入排序。
可以看出希尔排序希尔排序是改进了的插入排序。
特点:
子序列的构成不是简单的”逐段分割”,而是将相隔某个”增量”的记录组成一个自序列。这使得希尔排序中关键字较小的记录不是一步一步向前移,而是一次按照“增量”的大小跳跃式的往前移,从而在最后一堂增量为1时,序列已基本有序,只要做少量的比较和移动即可完成排序,因此希尔排序的时间复杂度比直接插入排序低。
下面以N=10个记录为例分析希尔排序的过程,记录如下:
49 38 65 97 76 13 27 49 55 04
第一趟排序选择增量为Increment=N/2=5,所以:
49 38 65 97 76 13 27 49 55 04
1A 1B
2A 2B
3A 3B
4A 4B
5A 5B
第二趟排序选择增量为Increment=Increment/2=2,第一趟排序结果如下:
13 27 49 55 04 49 38 65 97 76
1A 1B 1C 1D 1E
2A 2B 2C 2D 2E
第三趟排序选择增量为Increment=Increment/2=1,第二趟排序结果如下:
04 27 13 49 38 55 49 65 97 76
第四趟排序选择增量为Increment=Increment/2=0,即第三趟排序即完成整个排序,结果如下:
04 13 27 38 49 49 55 65 76 97
希尔排序算法的实现中,一个很重要的问题是增量序列的选择问题,因为它关系到希尔排序的性能,不同增量序列,性能会相差很远。通常情况下,第一个增量选为Increment=N/2,后面的增量选为Increment=Increment/2;
Java实现如下:
public class ShellSort {
public static void main(String[] args) {
// TODO Auto-generatedmethod stub
int[] a={49,38,65,97,76,13,27,50};
System.out.print("排序前:");
for(int i:a){
System.out.print(i+",");
}
shellSort(a);
System.out.print("排序后:");
for(int j:a){
System.out.print(j+",");
}
}
private static void shellSort(int[] a) {
// TODO Auto-generatedmethod stub
int i,j,d,temp;
d = a.length/2;
while(d>0){
for(i=d;i<a.length;i++){
temp=a[i];
j=i-d;
while(j>=0&&a[j]>temp){
a[j+d]=a[j];
j-=d;
}
a[j+d]=temp;
}
d/=2;
}
}
}
希尔排序时间复杂度为O(n^2)。