问题描述:给出一个确定在n个元素的任何排列中逆序对数量的算法,最坏情况需要 O(nlgn)时间(提示,修改归并排序)
思路: 看到lgn,想到用分治法。分治法的三个步骤——分解,解决,合并。最关键想清楚合并如何进行。
合并:在归并排序中合并时,左边序列第一个值若大于右边序列第一个值,则左边序列所有值与右边序列第一个值都构成逆序对。
#include<iostream>
using namespace std;
int Merge(int * A, int p, int q, int r)
{
int n1=q-p+1;
int n2=r-q;
int *L=new int[n1];
for(int l=0;l<n1;l++)
{
L[l]=A[p+l];
}
int *R=new int[n2];
for(int m=0;m<n2;m++)
{
R[m]=A[q+1+m];
}
int i=0;
int j=0;
int k=p;
int sum=0;
while(i<n1 && j<n2)
{
if(L[i]<=R[j])
A[k++]=L[i++];
else
{
A[k++]=R[j++];
sum+=(n1-i);
}
}
while(i<n1)
A[k++]=L[i++];
while(j<n2)
A[k++]=R[j++];
delete[] L;
delete[] R;
return sum;
}
int Inversion(int* A, int p, int r)
{
int invers=0;
if(p<r)
{
int q=(p+r)/2;
invers+=Inversion(A,p,q);
invers+=Inversion(A,q+1,r);
invers+=Merge(A,p,q,r);
}
return invers;
}
int main()
{
int A[5]={2,3,8,6,1};
int invers=Inversion(A,0,4);
cout<<invers<<endl;
return 0;
}