1.     和直接插入排序的关系

 

  在之前直接插入排序中提到过,希尔排序(Shell sort)是直接插入排序的变种方式之一,是一种更高效的改进版本。其基本思想如下:

  • 记录按下标的一定增量分组,对每组进行直接插入排序。
  • 不断地缩小增量,对每组进行直接插入排序,直至增量为1。

 

  由此可见,希尔排序本质就是多次使用直接插入排序。其优于直接插入排序的原因在之前也提到过,就是:直接插入排序对于基本有序的数组,拥有较高的性能。

 

  希尔入排序的时间复杂度是O(n^2)(只是针对最坏情况而言,平均的效率要远远高出其他时间复杂度为O(n^2)的排序算法),空间复杂度是O(1),但是在提供优秀性能的同时,打破了排序算法的稳定性。

 

  直接插入排序:http://www.cnblogs.com/jing-an-feng-shao/p/6165094.html

 

 

2.     希尔排序的实现

 

  希尔排序,又称缩小增量排序,其重点显然在于初始增量 d 的选取,以及每次增量 d 缩小的额度。一般来说,初始增量设为数组长度的一半,同时每次增量减半,直至 d=1,可以满足大多数的需求。

 

  下面用一个具体的场景,直观地体会一下希尔排序的过程。

场景:

现有一个无序数组,共7个数:89 45 54 29 90 34 68。

使用希尔排序法,对这个数组进行升序排序。

 

初始数组:

89 45 54 29 90 34 68

第一步:增量 d=3

29 45 34 68 90 54 89

第二步:增量 d=1

29 34 45 54 68 89 90

 

希尔排序的 Java 代码实现:

 1     public static void basal(int[] array) {
 2         if (array == null || array.length < 2) {
 3             return;
 4         }
 5         // 初始增量
 6         int d = array.length >>> 1;
 7         while (d > 0) {
 8             // d 次直接插入排序
 9             for (int i = 0; i < d; i++) {
10                 // 组内进行,相隔增量 d 项的直接插入排序
11                 for (int j = i + d; j < array.length; j += d) {
12                     int cur = array[j];
13                     boolean flag = false;
14                     for (int k = j - d; k > -1; k -= d) {
15                         if (cur < array[k]) {
16                             array[k + d] = array[k];
17                         } else {
18                             array[k + d] = cur;
19                             flag = true;
20                             break;
21                         }
22                     }
23                     if (!flag) {
24                         array[i] = cur;
25                     }
26                 }
27             }
28             // 每次增量减半
29             d >>>= 1;
30         }
31     }
basal

相关文章: