排好序的一:插入排序
void insertsort(int m[],unsigned size)
{
int j;
int i;
for(i=0;i!=size;++i)
{
int key=m[i];
for(j=i;j>=0;--j)
{
if(key<=m[j-1])
m[j]=m[j-1];
else
break;
}
m[j]=k;
}
}
算法的时间复杂度分析:该算法是消除逆序数类的算法,给定一个大小为n的排序,将他逆序,则两个排序总的逆序数为1+2+3+4+……………………+(N-1)=N(N-1)/2=(N^2-N)/2
交换次数就为上述结果,每次交换时间为1,则总时间为O(N^2)
二:希尔算法
对于一串有序数k1,k2,k3,k4,k5……,其中k1必须为1,且最大数小于排列个数的一种算法
这串数没个人都可以提出自己的排列,最初提出这个算法的人用的是1,2,4,8……2^k这一串有序数
例程如下
void shellsort(int m[],int size)
{
int i=size/2;
int x,y;
while(i!=0)
{
for(x=i;x!=size;++x)
{
for(y=x;y>=i;y=y-i)
{
int key=m[x];
if(key<=m[y-i])
m[y]=m[y-i];
else
break;
}
m[y]=key;
}
i/=2;
}
}
最好情况分析:如果输入是排好序的,则每次循环什么也不做,时间复杂度为O(N)
最坏情况分析:有一个坏数组1,9,2,10,3,11,4,12,5,13,6,14,7,15,8,16,则对于k1=1之外的所有k2,k3,k4……什么都不会做,故就类似于插入排序,故时间复杂度为O(N^2)
平均情况分析:太复杂,而且里面用到的数学公式也很复杂,暂时还未看懂如何推导的
三:堆排序
首先二话不说,上代码
void percdown(elements[],int i,int n)//将elements数组的第i项下滤
{
int key=elements[i];
int child;
while(2i+1<n)
{
child=2i+1;
if(child!=n-1&&elements[child]<elements[child+1])
child++;
if(key<elements[child])
{
elements[i]=elements[child];
i=child;
}
else
break;
}
elements[i]=key;
}
void headsort(elements[],int size)
{
for(int i=size/2;i>=0;--i)
{
percdown(elements[],i,size);
}
for(int i=n-1;i>0;--i)
{
swap(&elemens[0],&elements[i]);
percdown(elements,0,i);
}
}
算法分析
平均交换次数为NlogN-O(N)具体证明我还是没看懂,很尴尬
但我知一开始构造对的时间复杂度=N
构造堆的比较次数即为该堆的高度之和
有下面定理
2^(b+1)-1个节点的高度为b的二叉树的高度之和为2^(b+1)-1-(b+1)
该定理的证明用等比数列求和即可证出
三:分治排序
代码如下
void dividesort(int m[], int n[], int left, int right)//多添加一个n数组来保存合并后的数组否则在merge中需要重复的开空间删空间,会浪费时间
{
if (left >= right)//?
return;//?
else
{
int center = (left + right) / 2;
dividesort(m, n, left, center);
dividesort(m, n, center + 1, right);
mergesort(m, n, left, center, right);
}
}
void mergesort(int m[], int n[],int left, int center, int right)//我所用的是分类讨论写法,还有一种写法为设置哨兵写法
{
int x = left;
int y = center + 1;
int i = left;
while (x <= center&&y <= right)
{
if (m[x] < m[y])
{
n[i] = m[x];
++i;
}
else
{
n[i] = m[y];
++i;
}
}
while (x <= center)
n[i++] = m[x++];
while (y <= right)
n[i++] = m[y++];
for (int j = left; j <= right; ++j)
m[j] = n[j];
}
算法分析
T(1)=1
T(N)=2T(N/2)+N
T(N)/N=T(N/2)/(N/2)+1
根据叠缩求和就可求出
T(N)=NlogN+N
另一种方法可以用画树的方法,这里不方便画出