希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因DL.Shell於1959年提出而得名。希爾排序是記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
我們分割待排序記錄的目的是減少待排序記錄的個數,並使整個序列向基本有序發展。而如上面這樣分完組後,就各自排序的方法達不到我們的要求。因此,我們需要採取跳躍分割的策略:將相距某個“增量”的記錄組成一個子序列,這樣才能保證在子序列內分別進行直接插入排序後得到的結果是基本有序而不是局部有序。
初始時,有一個大小爲 5的無序序列。
(1)在第一趟排序中,我們不妨設 gap1 = N / 2 = 2,即相隔距離爲 5 的元素組成一組,可以分爲 5 組。
(2)接下來,按照直接插入排序的方法對每個組進行排序。
在第二趟排序中,我們把上次的 gap 縮小一半,即 gap2 = gap1 / 2 = 1 (取整數)。這樣每相隔距離爲 2 的元素組成一組,可以分爲 2 組。
(3)按照直接插入排序的方法對每個組進行排序。此時,排序已經結束。
/*
* 希爾排序
*/
static void shellSort1(int[] a,int n){
int grp = a.length;
while (true){
grp = grp/ 2;
//循環組
for(int i = 0;i < grp; i++){
//對每組的數據進行插入排序
for (int j = i + grp; j < a.length; j=j+grp) {
int temp = 0;
//最原始的插入排序
for (int k = j; k > 0; k=k-grp) {
if( a[k] < a[k-grp]){
temp=a[k-grp];
a[k-grp]=a[k];
a[k]=temp;
}
}
}
}
if (grp== 1) {//gap==1,跳出循環
break;
}
}
}