2. 插入排序—希爾排序(Shell Sort)
希爾排序是1959年由D.L.Shell提出來的,相對直接排序有較大的改進。希爾排序又叫縮小增量排序。
基本思想:
基本思想:演算法先將要排序的一組數按某個增量d(n/2,n為要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。
操作方法:
1、選擇一個增量序列t1,t2,....,tk,其中ti>tj,tk=1;
2、按增量序列的個數k,對序列進行k趟排序;
3、每趟排序,根據對應的增量ti,將帶排序列分割成若干長度為m的子序列,分別對個子序列進行直接插入排序。僅增量因子為1時,整個序列為一個表來處理,表長度即為整個序列的長度。
希爾排序的示例:
演算法實現:
我們簡單處理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n為要排序數的個數
即:先將要排序的一組記錄按某個增量d(n/2,n為要排序數的個數)分成若干組子序列,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。繼續不斷縮小增量直至為1,最後使用直接插入排序完成排序。
public class ShellSort3 { public static void main(String[] args) { int[] a = {12,43,65,7632,31,76,21,79,20}; System.out.println("排序前"); for(int i=0; i<a.length; i++){ System.out.print(a[i]+" "); } System.out.println(); shellSort(a, a.length); System.out.println("排序後"); for(int i=0; i<a.length; i++){ System.out.print(a[i]+" "); } } public static void shellSort(int[] a,int n){ int d,x,i,j; d=n/2; //設定增量 while(d>=1){ //當增量小雨1的時候推出迴圈,說明我們的資料已經拍好 for(i=d; i<n; i++){ x = a[i]; //獲取序列中的下一個資料,也就是我們要插入的資料 j = i-d; //序列中的前一個資料 while(j>=0 && x<a[j]){ a[j+d] = a[j]; j -= d; } a[j+d] = x; } d/=2; } } }
希爾排序時效分析很難,關鍵碼的比較次數與記錄移動次數依賴於增量因子序列d的選取,特定情況下可以準確估算出關鍵碼的比較次數和記錄的移動次數。目前還沒有人給出選取最好的增量因子序列的方法。增量因子序列可以有各種取法,有取奇數的,也有取質數的,但需要注意:增量因子中除1 外沒有公因子,且最後一個增量因子必須為1。希爾排序方法是一個不穩定的排序方法。