归并排序的应用1——求取逆序数组对

逆序组对:一个数组前面的数大于后面的数就算一组
举例:

{3,5,1,4,6}在这个数组中
<3 && pos > 0:	a[2]
<5 && pos > 1:	a[2]	a[3]
<1 && pos > 2:	NULL
<4 && pos > 3:	NULL
<6 && pos > 4:	NULL
所以一共3对
原理:在merge的过程中左右指针比较的过程中就可以比较,累计出逆序对的个数

代码:

/**
 * 归并排序应用1——求取逆序数对
 */

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

int merge(int a[],int l,int mid,int r)
{
	int p1 = l;
	int p2 = mid+1;
	int i = 0;
	int help[r-l+1];
	int ans = 0;
	while(p1 <= mid && p2 <= r)
	{
		ans += a[p1] > a[p2] ? (mid-p1+1):0;
		help[i++] = a[p1] < a[p2] ? a[p1++] : a[p2++];
	}
	while(p1 <= mid)
	{
		help[i++] = a[p1++];
	}
	while(p2 <= r){
		help[i++] = a[p2++];
	}

	int k = 0;
	for (int i = l; i <= r; ++i)
	{
		a[i] = help[k++];
	}
	return ans;
}

int GetReverserPair(int a[],int l,int r)
{
	if(l == r)	return 0;
	int mid = l + (r-l)/2;
	return GetReverserPair(a,l,mid)+GetReverserPair(a,mid+1,r)+merge(a,l,mid,r);
}

int main()
{
	int arr[5] = {3,5,1,4,6};
	int brr[5] = {4,3,5,7,0};
	int size_arr = sizeof(arr)/sizeof(arr[0]);
	int size_brr = sizeof(brr)/sizeof(brr[0]);
	int res = GetReverserPair(arr,0,size_arr-1);
	printf("%d\n", res);
	int res2 = GetReverserPair(brr,0,size_brr-1);
	printf("%d\n", res2);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bryant_xw/article/details/86439225