希尔排序(Shell Sort)是插入排序的一种,又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
将增量序列中的每一个步长 d 作为每一轮,将数据按照步长 d 分组,对于每组数据采用直接插入排序方法进行排序。
随着步长 d 的逐渐减小,所分成的组包含的数据越来越多。当最后步长 d 减小到1时,所有数据合成一组,构成一组有序序列,完成排序。
此处排序数据:{55,42,31,26,37,49,38,65,97,76}
/** * 希尔排序 * @Author distance */ public class ShellSort { public static void sort(int[] num) { int len = num.length; //System.out.print("增量序列:"); for (int d = len / 2; d > 0; d /= 2) { //System.out.print(d + " "); for (int i = d; i < len; i++) { int now = num[i]; int j; for (j = i; j >= d && now < num[j - d]; j -= d) { num[j] = num[j - d]; } num[j] = now; } } //System.out.println(); } public static void main(String[] args) { int[] num = {115,42,31,26,37,49,38,65,97,76}; ShellSort.sort(num); for (int i = 0; i < num.length; i++) { System.out.print(num[i] + " "); } } }
希尔排序的时间复杂度与增量(即步长 d)的选取有关。希尔排序不需要大量的辅助空间,和归并排序一样容易实现。希尔排序是基于插入排序的一种算法, 在此算法基础之上增加了一个新的特性,提高了效率。
希尔排序没有快速排序算法 O(n * logn) 快 ,中等大小规模表现良好,对规模非常大的数据排序不是最优选择。但是比 O(n^2) 复杂度的算法快得多。并且希尔排序非常容易实现,算法代码短而简单。
此外,希尔算法在最坏的情况下和平均情况下执行效率相差不是很多,而快速排序在最坏的情况下执行的效率会非常差。
综上,希尔排序的时间复杂度为 O(n^(1.3~2))。
由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以 shell 排序是不稳定的。
所以希尔排序是一个不稳定的排序算法。