排序演算法之希爾排序 java實現
阿新 • • 發佈:2018-12-23
知識準備
基礎概念
希爾排序:在直接插入排序的基礎上進行的優化,直接插入排序在n值小的時候效率比較高,在n很大的時候如果待排序序列基本有序,效率依然很高,時間效率可以提升為O(n)。希爾排序也稱之為縮小增量排序。
1.先選取一個小於n的整數d(步長),然後按照步長d將待排序序列分為d組,從第一個記錄開始間隔為d的為一個組。然後對各組內進行直接插入排序,一趟過後,間隔為d的序列有序,隨著有序性的改善,減少步長d重複進行 。直到d=1使得間隔為1的記錄有序,也就達到了整體有序
步驟分解
1.我們有序列 18、 24、 12 、15 、1 、27、 17 、19。我們以步長為序列長度除以2作為第一次的步長。以後每次都在原有的步長基礎上除以2取整。直到步長為1後進行直接插入排序為止。
如上圖所示,我們把序列根據步長8/2=4,將序列分成四組分別為:
[1,18]、[24,27]、[12,17]、[15,19]。
然後對各組進行直接插入排序得到最後的結果:
1、24、12、15、18、27、17、19
2.繼續縮減步長,在上一步的結果序列1、24、12、15、18、27、17、19基礎上使得步長為上一步步長除以2,即步長為4/2=2重複第一步如下圖所示。
根據步長分為兩組,[1,12,17,18]、[15,19,24,27]然後分別執行直接插入排序獲得結果:
1、15、12、19、17、24、18、27
3.我們已經看到序列逐步成為有序的過程,知道最後步長為1,如當前例項。執行到第三步步長為2/2=1,所以進行最後一步的直接插入排序,序列就是有序序列了。
得到最終序列:
1、12、15、17、18、19、24、27
程式碼實現
/**
* 希爾排序
*
* @param num
*/
public static void ShellSort(int num[]) {
int temp;
//預設步長為陣列長度除以2
int step = num.length;
while (true) {
step = step / 2;
//確定分組數
for (int i = 0; i < step; i++) {
//對分組資料進行直接插入排序
for ( int j = i + step; j < num.length; j = j + step) {
temp=num[j];
int k;
for( k=j-step;k>=0;k=k-step){
if(num[k]>temp){
num[k+step]=num[k];
}else{
break;
}
}
num[k+step]=temp;
}
}
if (step == 1) {
break;
}
}
}
注:網路上有些希爾排序寫的稍微有點問題,把希爾排序裡面的直接插入寫成了冒泡了。