排序(七)希尔排序

一、描述

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;

但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

直接插入排序 http://xia17.chukongxiang.top:8017/articles/2021/02/26/1614334116912.html

二、步骤

选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

按增量序列个数 k,对序列进行 k 趟排序;

每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

三、代码

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
/**
* 希尔排序
* @param a
*/
public void shellSort(int[] a){
int n = a.length ;
for(int gap = n/2 ; gap >0 ;gap /=2){
for(int i = gap ; i< n ;i++){
insertPlus(a,gap,i);
}
}
}

private void insertPlus(int[] a, int gap, int i) {
int temp = a[i] , j;
for(j=i-gap ; j >= 0 && temp < a[j] ; j -= gap){
a[gap + j] = a[j];
}
a[gap + j] = temp;
}

@Test
public void run2(){
int[] a= {5,4,6,7,2,8,1,3,9};
shellSort(a);
for (int i : a) {
System.out.print("," + i);
}
}

经过测试发现在速度上 希尔排序确实很快 。

img

希尔排序的复杂度

增量为2 最坏的情况 O(n^2)

增量为 3 最坏的情况 O(n^1.5)