欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

p-7-9求逆序对数目

程序员文章站 2024-03-16 09:36:40
...
1. 逆序对的定义

设A[1.n]是一个包含n个不同数的数组,如果在i<j的情况下,有A[i]>A[j], 则(i,j) 就称为A中的-一个逆序对。因为重
点是如何找出逆序对的数目,所以在这里假设数组的元素都不重复。

2. 求解思想

假设我们要对两个已经排好序的子序列L[1…N1],R[…N2]进行合并然后得出逆序对数目(这里注意在R的“左边”)。
如果L的某-一个元素比R的-一个元素大,比如L[2]> R[3],由于L跟R都是升序,那么L
往后的每个元素都比R[3]大。所以比R[3]大的数量就增加N1-2个,这里的N1代表L数组的长度。
循环下去,就可以找出L跟R数组里面所有的逆序对数目了
。这里不需要担心会发生重复计数。因为L跟R各自的逆序对数目之前已经求出,合并这一步比较的是两个子数组元素,不可能重复比较。

#include <bits/stdc++.h>
using namespace std;
int  count1 = 0;
void Merge(int a[], int low, int mid , int high){
	int i = low, j = mid + 1, k = 0;
	int *temp = (int *) malloc ((high - low + 1) * sizeof(int));
	while(i <= mid && j <= high){
		if(a[i] <= a[j])
			temp[k++] = a[i++];
		else{
			count1 += mid - i + 1;
			temp[k++] = a[j++];
		}
	}
	while(i <= mid)
		temp[k++] = a[i++];
	while(j <= high)
		temp[k++] = a[j++];
	for(k = 0, i = low; i <= high ; k++,i++)
		a[i] = temp[k];	
	free(temp);
}

void MergeSort(int a[], int s, int t){
	if(s < t){
		int mid = (s + t) / 2;
		MergeSort(a, s, mid);
		MergeSort(a, mid + 1, t);
		Merge(a, s, mid, t);
		
	}
}

void disp(int arr[], int n) {
	for(int i = 0; i < n; i++)
		cout << " "<< arr[i];
	cout << endl;
}

int main(){
	int n;
	cin >> n;
	int a[n]
	for(int i = 0; i < n; i++)
		cin >> a[i];
	disp(a,n);
	MergeSort(a, 0, n - 1);
	disp(a,n);
	cout << "逆序对的个数为:" << count1;
	return 0;
}
相关标签: 算法设计与分析