如何运用归并排序快速求得逆序对数目

逆序对数目可以直接穷举,但效率很低,O(n^2)级别.
可以用树状数组写.
这里介绍运用归并排序来求逆序对数目.

归并排序过程中,针对两个内部有序的串,
实现插入排序,即两串开头的元素,小的进入目标串,直到所有元素都输出.
假设左串当前元素比右串当前元素大.
那么左串剩下的元素一定都比右串当前元素大,都是逆序对.
那么这里逆序对就有 (mid - index_left + 1 )对

累加,最后获得最终的逆序对数目.

给出代码实现:

// a:目标数组  temp:临时数组
void merge(int left,int right,int mid)
{
    int index1, index2, num = left;
    for(int i=left;i<=right;i++)
        temp[i] = a[i];
    index1 = left; index2 = mid+1;//左右子序列开始的位置
    while(index1<=mid && index2<=right)
    {
        if(temp[index1] <= temp[index2])//取较小者放入数组
        {
            a[num++] = temp[index1++];
        }
        else
        {
            a[num++] = temp[index2++];
            res += (mid-index1+1);//左边没比完的元素和右边这个元素构成逆序对。
        }
    }
    while(index1 <= mid)
        a[num++] = temp[index1++];
    while(index2 <= right)
        a[num++] = temp[index2++];
}

void sort(int left,int right)
{
    if(left >= right)
        return;
    int mid = (left+right)/2;
    sort(left,mid);
    sort(mid+1,right);
    merge(left,right,mid);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值