并归排序

并归排序

逆序对

对于一个序列a,如果i<j,并且a[i]>a[j],则称a[i]与a[j]是一对逆序对。

并归排序

要统计一个序列里面有多少逆序对最简单的方法暴力统计逆序对。但是这样的时间复杂度是O(n2)的,在竞赛中一定时行的。那么,我们考虑这个问题。我们可不可以帮一段序列分为两段,然后排序,统计后一段的每一个与前一段的每一个是否构成逆序对,又因为后一段与前一段都是排好的序列,所以我们可以比较就得出结果。当然,我们先从最小的分堆向上调整。

int ans;
int merge(int low,int high,int a[]){
    int mid=(low+high)/2;
    int i=low,j=mid+1;
    for(int k=low;k<=high;k++){
        if(j>high || i<=mid && a[i]<=a[j])b[k]=a[i++];
        else b[k]=a[j++],ans+=mid-i+1;
    }
    for(int i=low;i<=high;i++)a[i]=b[i];
}

int mergesort(int low,int high,int a[]){
    if(low>=high)return 0;
    int mid=(low+high)/2;
    mergesort(low,mid,a);
    mergesort(mid+1,high,a);
    merge(low,high,a);
}

每次排序的复杂度在O(n),完全二叉树的深度是O(logn)所以每次并归排序的平均复杂度是O(nlogn)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值