希爾排序
將原本大量記錄數的記錄進行分組。分割成若干個子序列,然後在這些子序列內分別進行直接插入排序,當整個序列都基本有序時,再對全體記錄進行一次直接插入排序。
基本有序:基本有序的意思就是小的關鍵字基本在前面,大的基本在後面,不大不小的基本在中間。像{2,1,3,6,4,7,5,8,9};但像{2,9,3,6,4,7,5,8,1}9在第二位,1在倒數第一位就談不上基本有序。
分割策略:將相距某個“增量”的記錄組成一個子序列,這樣才能保證子序列內分別進行直接插入排序後得到的結果是基本有序而 不是局部有序;應當注意增量序列的最後一個增量值必須等於1纔行。
代碼:
#include<stdio.h>
#include<stdlib.h>
void Shell(int arr[], int len, int dk)//對一個分組中的序列使用直接插入排序算法
{
int tmp = 0;
int i = dk;
int j = i - dk;
for (i; i < len; ++i)
{
tmp = arr[i];
for (j = i - dk; j >= 0 && arr[j] > tmp; j -= dk)
{
arr[j + dk] = arr[j];
}
arr[j + dk] = tmp;
}
}
void ShellSort(int arr[], int len, int dk[], int dlen)
{
for (int i = 0; i < dlen; ++i)
{
Shell(arr, len, dk[i]);
}
}
int main2()
{
int arr[] = { 3, 12, 4, 32, 5, 436, 5, 47, 65, 8, 67, 84, 5, 234, 12 };
int len = sizeof(arr) / sizeof(arr[0]);
int dk[] = { 5, 3, 1 };//增量
int dlen = sizeof(dk) / sizeof(dk[0]);
ShellSort(arr, len, dk, dlen);
return 0;
}
希爾排序時間複雜度分析:
希爾排序的關鍵並不是隨便分組後各自排序,而是將相隔某個“增量”的記錄組成一個子序列,實現跳躍式的移動,使得排序的效率提高。迄今爲止沒有人找到一種最好的增量序列。不過大量的研究表明當增量序列爲
可以獲得不錯的效率,其時間複雜度爲。平均情況是Onlogn~O(n2)。