概述

1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

算法描述

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

  1. 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1
  2. 按增量序列个数k,对序列进行k 趟排序
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度

动图演示

img

算法实现

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 希尔排序
*
* @author LeDao
*/
public class Test {
public static void main(String[] args) {

int[] arr = new int[]{11, 3, 45, 2, 1, 7};
System.out.println("排序前:");
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
shellSort(arr);
System.out.println("排序后:");
for (int i : arr) {
System.out.print(i + " ");
}
}

public static void shellSort(int[] arr) {
for (int step = arr.length / 2; step > 0; step /= 2) {
for (int i = step; i < arr.length; i++) {
int j = i;
int temp = arr[j];
while (j - step >= 0 && arr[j - step] > temp) {
arr[j] = arr[j - step];
j = j - step;
}
arr[j] = temp;
}
}
}
}

运行结果

img

算法分析

希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第4版)》的合著者Robert Sedgewick提出的

PS.

搬运地址: 十大经典排序算法(动图演示) - 一像素 - 博客园 (cnblogs.com)