定义
希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。
它通过比较相距一定间隔的元素来进行,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。希尔排序目的为了加快速度改进了插入排序,交换不相邻的元素对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。
- 稳定性:根据 相等元素 在数组中的 相对顺序 是否被改变,排序算法可分为「稳定排序」和「非稳定排序」两类。
- 就地性:根据排序过程中 是否使用额外内存(辅助数组),排序算法可分为「原地排序」和「异地排序」两类。一般地,由于不使用外部内存,原地排序相比非原地排序的执行效率更高。
- 自适应性:根据算法 时间复杂度 是否 受待排序数组的元素分布影响 ,排序算法可分为「自适应排序」和「非自适应排序」两类。「自适应排序」的时间复杂度受元素分布影响,反之不受其影响。
- 比较类:比较类排序基于元素之间的 比较算子(小于、相等、大于)来决定元素的相对顺序;相对的,非比较排序则不基于比较算子实现。
图解
在此我们选择增量 gap=length/2,缩小增量以 gap = gap/2 的方式,用序列 {n/2,(n/2)/2...1} 来表示。
- 初始增量第一趟 gap = length/2 = 4
- 第二趟,增量缩小为 2
- 第三趟,增量缩小为 1,得到最终排序结果
性质
- 时间复杂度
- 最佳 O()
- 平均 O(nlogn)
- 最差 O()
- 空间复杂度
- 最差 O(1)
- 稳定性:不稳定
- 就地性:原地
- 自适应性:自适应
- 比较类:比较
Java
publicclassShellSort { // 内层循环其实就是插入排序publicstaticvoidsort(Comparable[] arr) { intj; for (intgap=arr.length/2; gap>0; gap/=2) { for (inti=gap; i<arr.length; i++) { Comparabletmp=arr[i]; for (j=i; j>=gap&&tmp.compareTo(arr[j-gap]) <0; j-=gap) { arr[j] =arr[j-gap]; } arr[j] =tmp; } } } publicstaticvoidmain(String[] args) { intN=2000; Integer[] arr=SortTestHelper.generateRandomArray(N, 0, 10); ShellSort.sort(arr); System.out.println(Arrays.toString(arr)); } }