高等排序5—逆序数

高等排序5

逆序数

数组a中,如果一组数满足a_{i}>a_{j},且i<j,那么这组数就称为逆序数。

        逆序数与冒泡排序法的交换次数相等。如果用冒泡排序法求逆序数,算法复杂度会达到O(n^{2})。可以使用归并排序法来求逆序数,对数组l和数组r进行排序,分别求出各自的逆序数。在合并数组l和数组r时,如果l[i]>r[j],计算n1-i就能得到当前有多少个与r[j]相关的逆序数,最后将逆序数加起来。

代码如下:

#include<iostream>
#define max 999
using namespace std;

int cnt = 0;
int l[max / 2 + 2], r[max / 2 + 2];

int  merge(int a[],int n,int left,int mid,int right) {
	int n1, n2;
	n1 = mid - left;
	n2 = right - mid;

	for (int i = 0; i < n1; i++) {
		l[i] = a[left+i];
	}
	for (int i = 0; i < n2; i++) {
		r[i] = a[mid + i];
	}

	l[n1] = r[n2] = max;
	int i=0, j = 0;
	for (int k = left; k < right; k++) {
		
		if (l[i] <= r[j]) {
			a[k] = l[i++];
		}
		else {
			a[k] = r[j++];
			cnt += n1 - i;
		}
	}

	return cnt;
}

int mergesort(int a[], int n, int left,int right){
	
	if (left + 1 < right) {
		int mid, v1, v2, v3;
		mid = (left + right) / 2;
		v1 = mergesort(a, n, left, mid);
		v2 = mergesort(a, n, mid, right);
		v3 = merge(a, n, left, mid, right);
		return v1 + v2 + v3;
	}
	else return 0;
	
}

int main() {

	int n,a[max];

	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	mergesort(a, n, 0, n);

	for (int i = 0; i < n; i++) {
		cout << a[i]<<" ";
	}

	cout << cnt;

	return 0;
}

读《挑战程序设计竞赛》第十八天(侵删)2021.3.12

( 2021.7.10 第一次修改)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值