希尔排序
2019-11-10 11:44:39 by冲冲
1、概念
希尔排序(shell排序),是插入排序(直接插入)的增强版。
特点是,在不断缩小增量的过程中,不断地排序,使得在最终使用插入排序时,序列已经基本有序。插入排序在操作基本有序的序列时效率倍增。
2、基本思想
把序列按步长gap分组,对每组小序列采用直接插入排序方法进行排序。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到1时,整个数据合成为一组,构成一组基本有序的序列,进行最后一趟插入排序,完成排序。

例析,
初始时,有一个大小为 10 的无序序列。
在第一趟排序中,设置 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。然后使用直接插入排序的方法对每个组进行排序。
在第二趟排序中,设置 gap2 = gap1 / 2 = 2 (取整数)。即每相隔距离为 2 的元素组成一组,可以分为 2 组。然后使用直接插入排序的方法对每个组进行排序。
在第三趟排序中,设置gap3 = gap2 / 2 = 1。 即相隔距离为 1 的元素组成一组,即只有一组。然后使用直接插入排序的方法对每个组进行排序。此时,排序已经结束。
希尔排序是不稳定性排序:图中有两个相等数值的元素 5 和 5,在排序过程中,两个元素位置交换了。
3、完整代码
1 public class ShellSort {
2 public static void main(String[] args){
3 int[] array = {9, 1, 2, 5, 7, 4, 8, 6, 3, 5};
4
5 // 调用希尔排序方法
6 ShellSort shell = new ShellSort();
7 System.out.print("排序前:\t\t");
8 shell.printAll(array);
9 shell.shellSort(array);
10 System.out.print("排序后:\t\t");
11 shell.printAll(array);
12 }
13
14 public void shellSort(int[] list) {
15 int gap = list.length / 2;
16
17 while (1 <= gap) {
18 // 把距离为 gap 的元素编为一个组,扫描所有组
19 for (int i = gap; i < list.length; i++) {
20 int j = 0;
21 int temp = list[i];
22
23 // 对距离为 gap 的元素组进行排序
24 for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap) {
25 list[j + gap] = list[j];
26 }
27 list[j + gap] = temp;
28 }
29
30 System.out.format("gap = %d:\t", gap);
31 printAll(list);
32 gap = gap / 2; // 减小增量
33 }
34 }
35
36 // 打印完整序列
37 public void printAll(int[] list) {
38 for (int value : list) {
39 System.out.print(value + "\t");
40 }
41 System.out.println();
42 }
43
44 }
1 排序前: 9 1 2 5 7 4 8 6 3 5 2 gap = 5: 4 1 2 3 5 9 8 6 5 7 3 gap = 2: 2 1 4 3 5 6 5 7 8 9 4 gap = 1: 1 2 3 4 5 5 6 7 8 9 5 排序后: 1 2 3 4 5 5 6 7 8 9