参考文章:
https://www.cnblogs.com/guoyaohua/p/8600214.html 十大经典排序算法最强总结(含JAVA代码实现)
https://mp.weixin.qq.com/s/sW0-YjOJELdMImtCo7hisQ 希尔排序就这么简单
希尔排序分析:
平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
O(n*logn) | O(n*log2 n) | O(n*log2 n) | O(1) | In-place | 不稳定 |
希尔排序原理:
我们来看下希尔排序的基本步骤,在此我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处我们做示例使用希尔增量。
希尔排序算法描述:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:
- 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
- 按增量序列个数k,对序列进行k 趟排序;
- 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
希尔排序原理图:
Java 代码实现:
代码一:
package com.sorting.algorithm;
public class ShellSort {
public static void sort(Comparable[] arr){
int n = arr.length;
// 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...
int h = 1;
while (h < n/3) h = 3*h + 1;
while (h >= 1) {
// h-sort the array
for (int i = h; i < n; i++) {
// 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
Comparable e = arr[i];
int j = i;
for ( ; j >= h && e.compareTo(arr[j-h]) < 0 ; j -= h)
arr[j] = arr[j-h];
arr[j] = e;
}
h /= 3;
}
}
public static void printArr(Comparable[] array){
for (int i = 0; i < array.length; i++) {
if(i != array.length-1)
System.out.print(array[i] + ",");
else
System.out.println(array[i]);
}
System.out.println();
}
public static void main(String[] args) {
Comparable[] array = { 58,36,70,22,88,64,1,32 };
System.out.println("排序之前:");
printArr(array);
System.out.println("-------------------------------");
System.out.println("排序过程");
sort(array);
System.out.println("-------------------------------");
System.out.println("排序之后:");
printArr(array);
}
}
代码二:
package com.sorting.algorithm;
public class ShellSort2 {
public static int[] shellSort(int[] array) {
int len = array.length;
int temp, gap = len / 2;
while (gap > 0) {
for (int i = gap; i < len; i++) {
temp = array[i];
int preIndex = i - gap;
while (preIndex >= 0 && array[preIndex] > temp) {
array[preIndex + gap] = array[preIndex];
preIndex -= gap;
}
array[preIndex + gap] = temp;
}
gap /= 2;
}
return array;
}
public static void printArr(int[] array){
for (int i = 0; i < array.length; i++) {
if(i != array.length-1)
System.out.print(array[i] + ",");
else
System.out.println(array[i]);
}
System.out.println();
}
public static void main(String[] args) {
int[] array = { 58,36,70,22,88,64,1,32 };
System.out.println("排序之前:");
printArr(array);
System.out.println("-------------------------------");
System.out.println("排序过程");
shellSort(array);
System.out.println("-------------------------------");
System.out.println("排序之后:");
printArr(array);
}
}
希尔排序代码测试:
代码一:
代码二: