C/C++ 求逆序对数

逆序对定义:对一个序列a[n],若i<j且a[i]>a[j],则a[i]与a[j]为逆序对。
如:序列 3, 2, 1 的逆序对数为2+1=3。

# include <bits/stdc++.h>
using namespace std;


TYPE array[ARRAYSIZE];  // 下标1~length
int length;  // array[]中使用的元素个数

注:以下各算法均会改变原序列

冒泡排序求解

逆序对数即冒泡排序中交换的次数。
平均时间复杂度:O(n^2)

long long calc_BS(TYPE a[], int n) {
	long long cnt = 0; bool f = true;
	for (int i = 1; i < n; i ++) {
	    for (int j = 1; j <= n-i; j ++) if (a[j] > a[j+1]) 
	    	swap(a[j], a[j+1]), cnt ++, f = false;
	    if (f) break;
	}
	return cnt;
}

// main
long long ans = calc_BS(array, length);

归并排序求解

递归对左右两半排序时,可把左右两半各自内部的逆序对数作为子问题计算。
平均时间复杂度:O(nlogn)

TYPE t[ARRAYSIZE];  // 临时数组
long long calc_MS(TYPE a[], int l, int r) {
	if (l >= r) return 0;
	if (r - l == 1) { 
		if (a[l] > a[r]) { swap(a[l], a[r]); return 1;}
		else return 0;
	}
	long long cnt = 0;
	int m = (l+r)>>1;
	cnt += calc_MS(a, l, m) + calc_MS(a, m+1, r);
	int p1 = l, p2 = m+1;
	for (int i = l; i <= r; i ++) {
		if (p1 > m) t[i] = a[p2 ++];
		else if (p2 <= r && a[p1] > a[p2]) t[i] = a[p2 ++], cnt += m+1 - p1;
		else t[i] = a[p1 ++];
	}
	for (int i = l; i <= r; i ++) a[i] = t[i];
	return cnt;
} 

// main
long long ans = calc_MS(array, 1, length);
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值