您的位置:首页 > 其它

归并排序--逆序对

2017-11-06 19:57 232 查看
按照刘汝佳说的,归并排序分三步

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

2.递归求解

3.合并子问题

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

先上代码

#include<iostream>

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<<ans;
return 0;

}

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

这是练习归并排序的经典例题,刘汝佳的书上也是这道题,归并排序的复杂度位nlogn,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: