逆序数与归并排序

逆序数指数组中前面的数大于后面的数的对数;a[i]>a[j]并且i<j;

将数组分为两组L(左)数组和(右)R数组;

将L数组与R数组分别从小到大排序;

在用R数组与左数组逐个比较,假如右数组的数比左数组的第一个数小,则cnt加上左数组的大小,右数组的数比左数组的第一个数大,比左数组的第二个数小则cnt加上左数组的数量减1;同理以次进行;

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MAX 55000
using namespace std;
const int mod=1e9+7;
int a[MAX];
int L[MAX],R[MAX];
ll mersort(int a[ ],int n,int left,int mid,int right )
{
    int i,j,k;
    ll cnt=0;
    int n1=mid-left;
    int n2=right-mid;
    for(i=0; i<n1; i++)
        L[i]=a[left+i];
    for(i=0; i<n2; i++)
        R[i]=a[mid+i];
    L[n1]=mod,R[n2]=mod;
    i=j=0;
    for(k=left; k<right; k++)
    {
        if(L[i]<=R[j])
        {
            a[k]=L[i++];//将数组从小到大排序 
        }
        else
        {
            a[k]=R[j++];//将数组从小到大排序 
            cnt+=n1-i;
        }
    }
    return cnt;

}
ll mergasort(int a[ ],int n,int left,int right)
{
    int mid;
    ll v1,v2,v3;
    if(left+1<right)//最少有个两数才能比较;
    {
        mid=(left+right)/2; 
        v1=mergasort(a,n,left,mid);
        v2=mergasort(a,n,mid,right);
        v3=mersort(a,n,left,mid,right);
        return v1+v2+v3;
    }
    else
        return 0;
}
int main( )
{
    ll n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
    }
    ll ans=mergasort(a,n,0,n);
    cout<<ans<<endl;
    return 0;
}

归并排序就是应用上述中的排序:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MAX 55000
using namespace std;
ll n;
const int mod=1e9+7;
int a[MAX];
int L[MAX],R[MAX];
void mersort(int a[ ],int n,int left,int mid,int right )
{
      int i,j,k;
      int n1=mid-left;
      int n2=right-mid;
      for(i=0;i<n1;i++) L[i]=a[left+i];
      for(i=0;i<n2;i++) R[i]=a[mid+i];
      L[n1]=mod,R[n2]=mod;
      i=j=0;
      for(k=left;k<right;k++)
      {
            if(L[i]<=R[j])
            {
                  a[k]=L[i++];
            }
            else
            {
                  a[k]=R[j++];
            }
      }

}
void mergasort(int a[ ],int n,int left,int right)
{
      int mid;
      ll v1,v2,v3;
      if(left+1<right)
      {
            mid=(left+right)/2;
            mergasort(a,n,left,mid);
            mergasort(a,n,mid,right);
            mersort(a,n,left,mid,right);
      }
}
int main( )
{
     cin>>n;
     for(int i=0;i<n;i++)
     {
           cin>>a[i];
     }
     mergasort(a,n,0,n);
     for(int i=0;i<n;i++)
     {
           if(i)
           {
                 cout<<" ";
           }
           cout<<a[i];
     }
     cout<<endl;
     return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值