算法思想
希爾排序是特殊的插入排序,直接插入排序每次插入前的遍歷步長爲1,而希爾排序是將待排序列分爲若干個子序列,對這些子序列分別進行直接插入排序,當每個子序列長度爲1時,再進行一次直接插入排序時,結果一定是有序的。常見的劃分子序列的方法有:初始步長(兩個子序列相應元素相差的距離)爲要排的數的一半,之後每執行一次步長折半。
希爾排序的過程演示如下:
代碼實現
#include <stdio.h>
#include <malloc.h>
void Shell_sort(int *a, int len); //函數聲明
int main(void)
{
int i;
int len;
int * a;
printf("請輸入要排的數的個數:");
scanf("%d",&len);
a = (int *)malloc(len * sizeof(int)); // 動態定義數組
printf("請輸入要排的數:\n");
for (i = 0; i < len; i++) { //數組值的輸入
scanf("%d",&a[i]);
}
Shell_sort(a, len); //調用希爾排序函數
printf("希爾升序排列後結果爲:\n");
for (i = 0; i < len; i++) { //排序後的結果的輸出
printf("%d\t",a[i]);
}
printf("\n");
return 0;
}
void Shell_sort(int *a, int len)
{
int i;
int j;
int temp;
int gap; //步長
for (gap = len / 2; gap >= 1; gap /= 2) { // 步長初始化爲數組長度的一半,每次遍歷後步長減半
for (i = 0 + gap; i < len; i += gap) { //對步長爲gap的元素進行直插排序,當gap爲1時,就是直插排序
temp = a[i]; //備份a[i]的值
j = i - gap; //j初始化爲i的前一個元素(與i相差gap長度)
while (j >= 0 && a[j] > temp) {
a[j + gap] = a[j]; //將在a[i]前且比temp的值大的元素向後移動一位
j -= gap;
}
a[j + gap] = temp;
}
}
}
時間複雜度
希爾排序的時間複雜度依賴於增量序列的函數,有人在大量的實驗後得出的結論:當n在某個特定的範圍後,在最優的情況下,希爾排序的時間複雜度爲O(n^1.3),在最差的情況下,希爾排序的時間複雜度爲:O(n^2).
空間複雜度
希爾排序的空間複雜度:O(1).
圖片來源:希爾排序演示圖片