归并排序求逆序数
今天,来学习一下归并排序求逆序数,首先,来学习归并排序
归并排序
归并归并,就是分为归和并,一个为递归函数将一串序列分为两个部,分直到这两个部分分别只有一个元素,然后就是合并函数,将两个部分,有序合并;
看代码:递归函数
void Mer(int a[], int b[],int l,int r)
{
int c[100010];
int mid=(l+r)/2;
if(l==r)
b[l]=a[l];
else
{
Mer(a,c,l,mid);//先将左边分为直到只有一个元素
Mer(a,c,mid+1,r);//再将右边同上
paixu(c,b,l,mid,r);//调用合并(排序)函数,使之变为有序数列
}
}
合并函数(排序)
void paixu( int a[], int b[],int i,int m,int n )
{
int j,k,l;
for(j=m+1,k=i; i<=m&&j<=n; k++)
{
if(a[i]<=a[j])//将数列的前半部分和后半部分每个元素相比较
b[k]=a[i++];//用b数组存比较后的数
else
{
b[k]=a[j];
j++;
}
}
while(i<=m)
b[k++]=a[i++];
while(j<=n)
b[k++]=a[j++];
}
好了,归并排序解决了,接下来就是求逆序数,解决了归并排序,求逆序数就简单了,只要在合并函数里加一句话就行,话不多说,康康代码:
long long int sum;//定义一个全局变量存逆序数;注意:多组输入时,主函数里。每循环一次,要初始化为零
void paixu( int a[], int b[],int i,int m,int n )
{
int j,k,l;
for(j=m+1,k=i; i<=m&&j<=n; k++)
{
if(a[i]<=a[j])//将数列的前半部分和后半部分每个元素相比较
b[k]=a[i++];//用b数组存比较后的数
else
{
b[k]=a[j];
sum=sum+m-i+1;//后面的大于前面的,而且这个是有序的序列,所以sum=sum+m-i+1
j++;
}
}
while(i<=m)
b[k++]=a[i++];
while(j<=n)
b[k++]=a[j++];
}