希尔排序

1.原理

希尔排序又称为缩小增量排序,是一种插入排序,排序速度比直接插入排序更加快捷。

对于长度为n的待排序数组a,希尔排序的基本思路如下:

A.选取整数gap(0<gap<n),将所有距离为gap的元素分为一组,总计有gap组;

B.对各个数组进行直接插入排序,数组变得稍微有序;

C.重复步骤A和B,对数组不断进行分组和排序,直至gap=1,此时对整个数组进行直接插入排序,排序完成。

2.实例

待排序数组a:[8, 1, 4, 2, 7, 0, 9, 6, 3, 5]

第一次:                                                                                        第二次:

gap=5,数组分类如下:                                                                       gap=2,数组分类如下:

a:[8, 1, 4, 2, 7, 0, 9, 6, 3, 5]                                                         a:[0, 1, 4, 2, 5, 8, 9, 6, 3, 7]

A: 8                 0                                                                         A: 0      4      5      9     3

B:     1                 9                                                                     B:     1      2      8      6      7

C:        4                 6                                                                  数组分为2组,对每组进行直接插入排序,结果如下:

D:            2                 3                                                              A: 0      3      4      5     9

E:                 7                 5                                                         B:     1     2      6      7      8

数组分为5组,对每组进行直接插入排序,结果如下:                                 a:[0, 1, 3, 2, 4, 6, 5, 7, 9, 8] 

A:0                  8                                                                         

B:    1                 9                                                                      第三次:

C:        4                 6                                                                  gap=1,即对整个数组进行直接插入排序:

D:           2                 3                                                               a:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

E:               5                 7                                                          

a:[0, 1, 4, 2, 5, 8, 9, 6, 3, 7]           

3.代码

 1 public class ShellSortTest {
 2            // 遍历数组
 3     public static void printAll(int[] a) {
 4         for (int value : a) {
 5             System.out.print(value + "	");
 6         }
 7         System.out.println();
 8     }
 9 
10           //希尔排序
11     public static void shellSort(int a[]) {
12         int gap = a.length / 2;              //取初始步长为n/2
13         while (gap>=1) {
14                    // 把距离为 gap 的元素编为一个组
15             for (int i = gap; i < a.length; i++) {
16                 int temp = a[i];            //待插元素
17                 int j = i - gap;            
18 
19                     // 对距离为 gap 的元素组进行直接插入排序
20                 while ( j >= 0 && temp < a[j]) {          
21                     a[j + gap] = a[j];         //元素后移
22                     j = j - gap;
23                 }
24                 a[j + gap] = temp;        //在空出的位置插入待插元素
25             }
26             System.out.format("gap="+gap+":"+"	");
27             printAll(a);
28             gap = gap / 2;           // 减小增量
29         }
30     }
31     public static void main(String[] args) {
32         int a[]= { 8, 1, 4, 2, 7, 0, 9, 6, 3, 5 };
33         System.out.print("排序前:	");
34         ShellSortTest.printAll(a);
35         ShellSortTest.shellSort(a);
36         System.out.print("排序后:	");
37         ShellSortTest.printAll(a);
38     }
39 }

4.时间复杂度

希尔排序的时间复杂度与步长的选取有关,例如希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(),

希尔排序时间复杂度的下界是n*log2n。

                                             

原文地址:https://www.cnblogs.com/jfl-xx/p/4842520.html