归并排序--逆序对

按照刘汝佳说的,归并排序分三步

1.划分问题,即把序列分成元素尽量相等的两半

2.递归求解

3.合并子问题

其实就是把一个序列不断的二分,直到只有两个元素的时候,然后排序,然后返回,再排序。

先上代码

#include
using namespace std;
long long a[100005],t[100005];
long long ans=0;
void mergesort(int lb,int ub)
{
if(lb==ub)return;
int mid=(lb+ub)/2;
int i=lb,j=mid+1,num=lb;
mergesort(lb,mid);
mergesort(mid+1,ub);
while(i<=mid&&j<=ub)
{ //这里就是排序,即从小到大依次放回到数组中
if(a[i]>a[j]){
t[num++]=a[j++];
ans+=mid-i+1; //这里就是求逆序对的关键点,如果去掉这一句,就变成了裸的归并排序,因为两个子序列是有序的,所以
} //当前一个子序列的元素大于后一个子序列的元素时,那么前一个子序列的那个元素后面的元素也就都大于后一个子
else t[num++]=a[i++]; //序列的元素,即mid-i+1
}
while(i<=mid) //如果一个序列为空的时候,就把另一个序列依次放回去
t[num++]=a[i++];
while(j<=ub)
t[num++]=a[j++];
for(int i=lb;i<=ub;i++)
a[i]=t[i];
}
int main()
{
int n;
cin>>n;
for(long long i=1;i<=n;i++)
cin>>a[i];
mergesort(1,n);
cout<return 0;
}


这里对应了codevs的1688求逆序对

这是练习归并排序的经典例题,刘汝佳的书上也是这道题,归并排序的复杂度位nlogn,


你可能感兴趣的:(归并排序--逆序对)