希爾排序是簡單排序中插入排序的一種更高效的改進版本,可是直接插入排序是穩定的,希爾排序是不穩定的。java
其基本思路是:算法
在示例中先對數組進行 4 分組,每組進行一次插入排序,再進行 2 分組的插入排序,最後步長爲 1 ,進行一次普通的插入排序。數組
雖然在示意圖中對每一分組單獨進行了插入排序,但這只是便於理解,實際上,能夠在數組的一次遍歷過程當中對全部分組進行插入排序。下圖是 4 分組插入排序的示意圖。spa
public class ShellSort { public static void sort(int[] arr) { for (int i = arr.length >> 1; i > 0; i >>= 1) { insertSort(arr, i); } } private static void insertSort(int[] arr, int delta) { for (int i = delta; i < arr.length; i ++) { int j = i; int temp = arr[j]; while (j >= delta && temp < arr[j-delta]) { arr[j] = arr[j-delta]; j-=delta; } arr[j] = temp; } } }
毫無疑問,希爾排序與直接插入排序最大的不一樣在於設置了步長序列,在上面的代碼中,設置的步長序列直接是上一個步長除以 2 直到步長爲 1 ,但實際上,效率最高的步長序列並不是是上述結構,不一樣的序列的排序快慢不一樣,能夠閱讀相關資料,得知其餘步長的具體細節。code
因爲不一樣步長會影響到排序算法的時間複雜度,因此沒法肯定算法的平均時間複雜度,不過根據維基百科上所說其時間複雜度在 $O(nlog_2n)$ 和 $O(n^2)$ 之間。blog
而空間複雜度,因爲沒有用到額外空間,所以其空間複雜度爲 $O(1)$ 。排序
雖然直接插入排序是穩定的,可是因爲希爾排序經過步長分割數組,在分組排序中其天然順序會被打亂,所以他是不穩定排序。ip