逆序对-归并排序

#include<bits/stdc++.h>
using namespace std;
int cnt;
int a[1005],b[20000];
void Merge(int *c,int *d,int l,int m,int r)
{
	int i = l;
	int j = m+1;
	int k = l;
	while((i<=m)&&(j<=r))
	{
		if(c[i]<=c[j])
		d[k++] = c[i++];
		else{
                d[k++] = c[j++];
                cnt += m-i+1;//原归并排序中加了这一步
            }
	}
	if(i > m)
		for(j;j <= r;j ++)
        {
			d[k++] = c[j];
        }
	else for(i;i <= m;i ++)
			d[k++] = c[i];

}
void MergePass(int *x,int *y,int s,int n)
{
	int i = 0;
	while(i+2*s < n)
	{
		Merge(x,y,i,i+s-1,i+2*s-1);
		i += 2*s;
	}
	if(i+s < n)
		Merge(x,y,i,i+s-1,n-1);
	else for(i;i < n;i ++)
		y[i] = x[i];
}
void MergeSort(int *a,int n)
{
	int s = 1;
	while(s < n)
	{
		MergePass(a,b,s,n);
		s += s;
		MergePass(b,a,s,n);
		s += s;
	}
}
int main()
{
    int n;
    while(cin>>n&&n)
    {
        cnt = 0;
        for(int i = 0; i < n; i++)cin>>a[i];
        MergeSort(a,n);
        cout<<cnt<<endl;
    }



    return 0;
}

归并排序合并的时候是将两个有序序列中的每个数依次比较排序,上图为排序的一个过程,当前第i个数大于第j个数,j与i到mid中每一个数均构成逆序对,排序时将直接j排入已排好序列,期间相当于j与i到mid之间的每个数均交换了一遍,即

交换次数 = mid - i +1。

猜你喜欢

转载自blog.csdn.net/wys5wys/article/details/81210604