希爾排序又稱“縮小增量排序”。
它的基本思想是:先將整個待排記錄序列分割成若干子序列分別進行直接插入排序,待整個序列中的記錄”基本有序”時,(當增量爲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)。