相比如冒泡排序、選擇排序、直插排序等一些簡單的排序算法,希爾排序是第一個在時間複雜度上突破O(n^2)的,其時間複雜度爲O(n^1.5),但是希爾排序是一種不穩定的排序方式。
希爾排序實際上是直插排序(http://blog.csdn.net/xgcyangguang/article/details/51217354)的優化,直插排序是在後面的數據中找到最小的插入到當前位置,而希爾排序在找到最小的數據這個過程中就把較大的數據移到了後面,把較小的數據放到了前面,讓整個數據變得相對有序。
希爾排序不再是一個一個尋找交換的數據,而是通過設定的間隔interval跳躍式的尋找要交換的數據,然後再不斷的縮小間隔,當然最後一次排序的時候間隔要是1。
//希爾排序算法
void ShellSort (int H[],int length)
{
int i = 0;
int j = 0;
int interval = length; //設置排序間隔增量,這是希爾排序的精髓
do
{
interval = interval / 3 + 1; //增量每次遞減,但是要保證最後一次的增量是1,結果纔會準確
for (i = interval + 1; i < length; i++) //從增量下標+1的位置開始與前面的數據比較
{
if (H[i] < H[i - interval]) //如果後面的數據小於前面的數據
{
H[0] = H[i]; //先把數據放到首位備份
for (j = i - interval; j > 0 && H[0] < H[j]; j -= interval)
{
H[j + interval] = H[j]; //數據依次向後移,尋找新數據插入的位置
}
H[j + interval] = H[0]; //插入數據
}
}
}
while (interval > 1);
}
希爾排序是通過增量來減少時間複雜度的,因此增量的選擇就變得尤爲關鍵了,在這裏增量選擇了數據總長度/3,迄今爲止還沒有找到一種最好的增量序列,不過一般來說增量爲2^(t + k -1) - 1(其中0 <= k <= t <= [log])時,可以獲得較好的時間複雜度O(n^1.5)