希尔排序
算法描述:希尔排序是插入排序的一种改进,主要是为了解决当较小的数据大都出现在数组后面时导致的移动次数明显增多的问题,思想是使用一个不断缩小的增量gap将数组元素分组,在每个分组内部先进行插入排序,当gap减少到1时整个数组元素分在一组,最后进行一次插入排序,整个排序过程结束。
算法时间复杂度:最好情况:当数据已经排好序的情况下:O(N1.3);最坏情况:O(N2);平均情况:O(NlogN)
算法空间复杂度:O(1)
算法稳定性:不稳定
算法实现:希尔排序ShellSort的实现如下:
void shellSort(vector<int>&vt) {
for(int gap = vt.size() / 2; gap > 0; gap >>= 1) {//先间隔一半,再四分一,二分一...一直到相邻两个换。
int i = gap;
while(i < vt.size()) {//i从gap不断递增
int j = i;
while(j >= gap && vt[j] <= vt[j - gap]) {//gap是标志,一定要从后往前,否则次数不够
swap(vt[j],vt[j - gap]);
j -= gap;
}
i++;
}
}
}
如下图,假设有7个点:
第一轮:
依次类推,它是隔着比较来比较交换的。
下面是学校的填空题,类似的,但是又有不一样的地方,可以加深你对希尔排序的印象。
#include <stdio.h>
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 <stdio.h>
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;
}