希爾排序算法
希爾排序(Shell Sort)是一種插入排序算法,因D.L.Shell於1959年提出而得名。又稱作縮減增量排序。基本思考:希爾排序是優化的插入排序。基本的思想還是插入排序(插入置換,讓子序列有序),它通過比較相距一定間隔的元素,所用的距離隨算法進行而減少,直到相距爲1爲止。
①取數據的增量(希爾建議是hк=N/2和hк=hк+₁/2)
gap={5,2,1}
②在增量基礎上,分獨立的子數組
gap=5: {a[5] a[0]}, {a[6] a[1]}, {a[7] a[2]}, {a[8] a[3]} , {a[9] a[4]}
gap=2: {a[2] a[0]}
{a[4] a[2] a[0]}
{a[6] a[4] a[2] a[0]}……
……
{a[3] a[1]}
{a[5] a[3] a[1]}…….
gap=1: {a[1] a[0]}——類似直接插入排序
{a[2] a[1] a[0]}……
③在子數組內,執行插入排序
int[] data = { 9, 1, 2, 5, 7, 4, 8, 6, 3, 5 };
public static void shellSort(int[] d) {
int j;
//縮減距離:gap=hк/2 →5,2,1
for(int gap=d.length/2;gap>0;gap/=2) {
for(int i=gap;i<d.length;i++) {//增量插入排序
Integer tmp=d[i];
for(j=i;j>=gap&&tmp.compareTo(d[j-gap])<0;) {//j>=gap
d[j]=d[j-gap];//插入
j-=gap;//尋找下標j→tmp值,在同距離上的子數列上,合理的位置
//a[8]=5,在a[6],a[4],a[2],a[0],合理的位置是j=6;
}
System.out.println(gap+"=="+i+"=="+j);
d[j]=tmp;
}
}
//打印排序結果
for(int a:d) {
System.out.print(" "+a);
}
}
3.分析
希爾算法的分析是極其複雜的。平均運行時間O(N¹´³)。
當n較大時,那麼希爾排序運行很快,大概在O(n¹´²⁵)。
思考:
基礎:其算法的精髓在“縮減和增量”二字上。
開始時增量較大,分組較多,每組記錄數目少,故每組內直接插入排序較快。
後來增量gap逐漸縮小,分組數逐漸減少,而各組的記錄數目逐漸增多,但由於已經在距離上排過序,使文件較接近於有序狀態,所以新的一趟排序過程也較快。
因此,希爾排序在效率上較直接插入排序有較大的改進。