=
希尔排序
希尔排序的快慢处于中等水平,我们知道插入排序的平均时间复杂度为O(n^2),但也取决于序列的混乱程度,越混乱插入排序越慢,为了减小混乱程度加快插入排序的速度,希尔排序就派上用场了(可以说希尔排序是插入排序的加速版)
希尔排序其实类似于插入排序,插入排序是要在间隔为1的为基础上选择未排序集合的第一个元素在已排序的元素集合间插入适当位置,而希尔排序则是不断以间隔G进行插入排序操作
间隔G不是随便取的间隔,是有规定的G={1,4,13,40,121…}
G中每一个元素是前一个的3倍+1,G取到什么时候位置呢,不可能无限取下去,这里规定G>N就停止了(N是待排序序列的元素个数),然后把G中所有元素从大到小取出作为间隔距离一次进行插入排序
看图就明白了
代码
#include<stdio.h>
#include<stack>
using namespace std;
typedef long long ll;
ll cnt=0;
int insertsort(int A[],int n,int g)//插入排序
{
for(int i=g+1;i<=n;i++)
{
int pos=i-g;
int temp=A[i];
while(A[pos]>temp&&pos>=1)
{
A[pos+g]=A[pos];
pos-=g;
cnt++;//移动次数
}
A[pos+g]=temp;
}
return 0;
}
int shellsort(int A[],int m,int G[],int n)//希尔排序
{
for(int i=m-1;i>=0;i--)
{
insertsort(A,n,G[i]);
}
printf("%d\n",cnt);
return 0;
}
int main()
{
int n;
scanf("%d",&n);
int a[n+5];
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int G[100];
int Gnum=0;
int number=1;
while(number<=n)
{
s.push(number);
G[Gnum++]=number;
number=number*3+1;
}
for(int i=Gnum-1;i>=0;i--) printf("%d ",G[i]);
printf("\n");
shellsort(a,Gnum,G,n);
for(int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}