參考文章:
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);
}
}
希爾排序代碼測試:
代碼一:
代碼二: