上篇blog中介紹的直接插入排序,希爾排序就是對直接插入排序的一個優化。比如有這么一種情況:對一個無序數組進行從小到大的排序,但是數組的最后一個位置的數是最小的,我們要把它挪到第一個位置,其他位置的都要往后移動,要是這個數組非常大,那么直接插入排序的開銷就非常大。
現在有一個array,希爾排序就是設定一個增量incrementNum(0<incrementNum<array.length)。
先從array[0]開始,以incrementNum為增量的進行直接插入排序,直到數組末尾,然后從array[1]開始重復:以incrementNum為增量的進行直接插入排序; 然后從array[1]開始重復......一直到array[n]。
然后取一個小於上一步增量的新的增量(比如設置為incrementNum/2),對前一個步驟的結果array進行遍歷,直接插入排序....
再取小於上一步增量的新的增量,重復進行:遍歷,直接插入排序
直到新的增量小於1之后再退出循環
步驟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,退出循環。
java實現代碼如下:
/** * 希爾排序 * @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; } }