希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
接下来我们以数组:82 ,31 ,29 ,71, 72, 42, 64, 5, 110为例
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
元素 | 82 | 31 | 29 | 71 | 72 | 42 | 64 | 5 | 110 |
该数组长度为9,初始增量先设置为 数组长度的二分之一,向下取整,此处就是4
那我们就可以把以上数组分为以下四个子数组,然后对每个子数组分别进行插入排序
子数组1
下标 | 0 | 4 |
元素 | 82 | 72 |
子数组2
下标 | 1 | 5 |
元素 | 31 | 42 |
子数组3
下标 | 2 | 6 |
元素 | 29 | 64 |
子数组4
下标 | 3 | 7 |
元素 | 71 | 5 |
排序完得到以下数组:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
元素 | 72 | 31 | 29 | 5 | 82 | 42 | 64 | 71 | 110 |
重新设置增量 = 之前增量的1/2 即是4/2=2
在增量为2的前提下,分成以下两个子数组,分别对其进行插入排序
子数组1
下标 | 0 | 2 | 4 | 6 | 8 |
元素 | 72 | 29 | 82 | 64 | 110 |
子数组2
下标 | 1 | 3 | 5 | 7 |
元素 | 31 | 5 | 42 | 71 |
排序完的数组应该是:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
元素 | 29 | 5 | 64 | 31 | 72 | 42 | 82 | 71 | 110 |
重新设置增量 = 之前增量的1/2 即是2/2=1
增量为1的时候,就是对整个数组分成一组,进行插入排序
最后得到:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
元素 | 5 | 29 | 31 | 42 | 64 | 71 | 72 | 82 | 110 |
希尔排序(Java):
public static int[] shellSort(int[] elements) {
int temp = 0;
if(null == elements || 1 >= elements.length) {
// do nothing
} else if(2 == elements.length) {
if(elements[0] > elements[1]) {
temp = elements[0];
elements[0] = elements[1];
elements[1] = temp;
}
return elements;
} else {
int increment = elements.length >> 1;// 增量
while(increment >= 1) {
for(int g = 0; g < increment; g++) {
// 遍历组 组数:increment
for(int i = (g+increment); i < elements.length; i+=increment) {
// 对每一组的元素进行插入排序
int k = i - increment;
int n = i;
while(k >= 0) {
if(elements[n] < elements[k]) {
temp = elements[n];
elements[n] = elements[k];
elements[k] = temp;
n = k;
k = k - increment;
} else {
k = -1;
}
}
}
}
System.out.println("increment="+increment+",elements="+Arrays.toString(elements));
System.out.println("------------------------------------------------");
increment = increment >> 1;
}
}
return elements;
}
测试代码:
public static void main(String[] args) {
int[] array = {82 ,31 ,29 ,71, 72, 42, 64, 5, 110};
shellSort(array);
}
测试结果:
increment=4,elements=[72, 31, 29, 5, 82, 42, 64, 71, 110]
------------------------------------------------
increment=2,elements=[29, 5, 64, 31, 72, 42, 82, 71, 110]
------------------------------------------------
increment=1,elements=[5, 29, 31, 42, 64, 71, 72, 82, 110]
------------------------------------------------