常用演算法——希爾排序(Shell Sort)
阿新 • • 發佈:2018-12-24
1.什麼是希爾排序
希爾排序的核心思想是使陣列中任意間隔為g的元素都是有序的。首先取小於陣列長度的一個數g1作為第一個間隔值,對全部陣列進行兩兩分組,在分組內實現排序。然後取g2(g2小於g1,g1到g2應有一個明確的增量演算法)再對陣列進行兩兩分組,再實現組內排序。重複上述操作直到gt=1為止,此時陣列排序已經完成。
2.為什麼使用希爾排序
希爾排序是對插入排序的改進,希爾排序在大陣列的排序上陣列越大相對於插入排序和選擇排序的優勢越大。相比較於更高階的排序演算法,中等大小的陣列排序更適合使用希爾排序,因為它執行時間是尚可接受的,同時代碼量小,且不需要額外的儲存空間。
3.關於增量和時間複雜度
不難看出,影響希爾排序效率的一大因素就是其增量的選擇,目前尚未能從數學上得出“效率最高”的增量,也就是說目前尚未有明確的時間複雜度。通用的時間複雜度為O(n^1.3),最壞情況為O(n^2)。對於絕大多數情況,希爾排序是遠快於O(n^2)的排序演算法的。
4.程式碼實現(Java)
public class Shell {
/**
* 比較兩者大小
*
* @param v
* @param w
* @return 當v小於w,返回true,反之返回false
*/
private boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
/**
*
* @param array
* 值所在的陣列
* @param i
* 排序前靠前的值的下標
* @param j
* 排序前靠後的值的下標
*/
private void exch(Comparable[] array, int i, int j) {
Comparable t = array[i];
array[i] = array[j];
array[j] = t;
}
public void sort(Comparable[] array) {
int size = array.length;
int gap = 1; // 間隔值初始
int dt = 3; // 增量幅度
while (gap < size / dt)
gap = dt * gap + 1;
System.out.println("gap:"+gap);
while (gap >= 1) {
for (int i = gap; i < size; i++) {
for (int j = i; j >= gap && less(array[j], array[j - gap]); j -= gap) {
exch(array, j, j - gap);
}
}
gap = gap / dt;
}
}
}