希尔排序
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("排序前: "); 8 shell.printAll(array); 9 shell.shellSort(array); 10 System.out.print("排序后: "); 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: ", 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 + " "); 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