算法描述:希尔排序是插入排序的一种改进,主要是为了解决当较小的数据大都出现在数组后面时导致的移动次数明显增多的问题,思想是使用一个不断缩小的增量gap将数组元素分组,在每个分组内部先进行插入排序,当gap减少到1时整个数组元素分在一组,最后进行一次插入排序,整个排序过程结束。
算法时间复杂度:最好情况:当数据已经排好序的情况下:O(N1.3);最坏情况:O(N2);平均情况:O(NlogN)
算法空间复杂度:O(1)
算法稳定性:不稳定
算法实现:希尔排序ShellSort的实现如下:
void ShellSort(vector<int>&a){
for(int gap=a.size()/2;gap>0;gap/=2){
for(int i=gap;i<a.size();i++){
int j=i;
int temp=a[j];
for(;j>=gap && temp<a[j-gap];j-=gap)
a[j]=a[j-gap];
a[j]=temp;
}
}
}
如下图,假设有7个点:
第一轮:
依次类推,它是隔着比较来比较交换的。
下面是学校的填空题,类似的,但是又有不一样的地方,可以加深你对希尔排序的印象。
#include
void PrintArray(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%5d",a[i]);
}
void ShellSort(int a[],int n)
{
int i,j,k,m,t,span;
int d[]={
7,5,3,1};
for(m=0;m<4;m++)
{
span=__(1)__;
for(k=0;k<__(2)__;k++)
{
for(__(3)__;i<n-span;i=i+span)
{
t=a[i+span];
for(j=i;j>-1&&a[j]>t;__(4)__)
{
a[j+span]=a[j];
}
__(5)__;
}
}
}
}
int main()
{
int a[15]={
701,653,98,107,774,497,208,474,346,611,855,134,422,21,1},i;
ShellSort(a,15);
PrintArray(a,15);
return 0;
}
题解:
#include
void PrintArray(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%5d",a[i]);
}
void ShellSort(int a[],int n)
{
int i,j,k,m,t,span;
int d[]={
7,5,3,1};
for(m=0;m<4;m++)
{
span=d[m];
for(k=0;k<n-span;k++)
{
for(i=k;i<n-span;i=i+span)
{
t=a[i+span];
for(j=i;j>-1&&a[j]>t;j-=span)
{
a[j+span]=a[j];
}
a[j+span]=t;
}
}
}
}
int main()
{
int a[15]={
701,653,98,107,774,497,208,474,346,611,855,134,422,21,1},i;
ShellSort(a,15);
PrintArray(a,15);
return 0;
}