上篇blog中介紹的直接插入排序,希爾排序就是對直接插入排序的一個優化。好比有這麼一種狀況:對一個無序數組進行從小到大的排序,可是數組的最後一個位置的數是最小的,咱們要把它挪到第一個位置,其餘位置的都要日後移動,要是這個數組很是大,那麼直接插入排序的開銷就很是大。java
如今有一個array,希爾排序就是設定一個增量incrementNum(0<incrementNum<array.length)。數組
先從array[0]開始,以incrementNum爲增量的進行直接插入排序,直到數組末尾,而後從array[1]開始重複:以incrementNum爲增量的進行直接插入排序; 而後從array[1]開始重複......一直到array[n]。優化
而後取一個小於上一步增量的新的增量(好比設置爲incrementNum/2),對前一個步驟的結果array進行遍歷,直接插入排序....spa
再取小於上一步增量的新的增量,重複進行:遍歷,直接插入排序code
直到新的增量小於1以後再退出循環blog
步驟1:好比如今有數組{82 ,31 ,29 ,71, 72, 42, 64, 5,110} 第一次取增量設置爲array.length/2 = 4 先從82開始以4爲增量遍歷直到末尾,獲得(82,42) 排序獲得{42 ,31 ,29 ,71, 72, 82, 64, 5,110}。 而後從第二個數31開始重複上一個步驟,獲得(31,64) 排序獲得{42 ,31 ,29 ,71, 72, 82, 64, 5,110}....... 以4爲增量的遍歷完數組以後,獲得的結果是{42 ,31,5,71,72,82,64,29,110}排序
而後從新區增量,這兒設定爲incrementNum/2 = 2,對{42 ,31,5,71,72,82,64,29,110}重複步驟1。 完事以後,在取新的增量,重複步驟1。 直到取到的增量小於1,退出循環。rem
java實現代碼以下:class
/** * 希爾排序 * @param arrays 須要排序的序列 */ public static void sort(int[] arrays){ if(arrays == null || arrays.length <= 1){ return; } //增量 int incrementNum = arrays.length/2; while(incrementNum >=1){ for(int i=0;i<arrays.length;i++){ //進行插入排序 for(int j=i;j<arrays.length-incrementNum;j=j+incrementNum){ if(arrays[j]>arrays[j+incrementNum]){ int temple = arrays[j]; arrays[j] = arrays[j+incrementNum]; arrays[j+incrementNum] = temple; } } } //設置新的增量 incrementNum = incrementNum/2; } }