求序列逆序数

序列逆序数:

由1,2,…,n 组成的一个有序数组称为一个n级排列。在一个排列中如果一对数的前后位置与大小顺序相反,即大数排在小数的前面,则称它们为一个逆序。一个排列中所有逆序的总和称为该排列的逆序数。

那么,如何求解一个序列的逆序数呢?暴力法是问题解的最简单的方法,下面给出核心代码:

int InversionNumber(int num[], int N){
	int count = 0;
	for (int i = N - 1; i > 0; i--) {
		for(int j = 0; j < i; j++) {
			if(num[j] > num[i]) 
				count++;
		}
	}
	return count;
}
直接根据定义暴力求解固然简单,但是往往效率不高,O(n^2)的复杂度在数据规模较大的时候,是不很乐观的。

归并求逆序简单原理:

归并排序是分治的思想,具体原理自己去看书吧。利用归并求逆序是指在对子序列 s1和s2在归并时,若s1[i]>s2[j](逆序状况),则逆序数加上s1.length-i,因为s1中i后面的数字对于s2[j]都是逆序的。下面为核心代码

void merge(int l,int mid,int r,int arr[])
{
	int i=l,j=mid+1;
	int k=0;
	while(i<=mid&&j<=r)
	{
		if(arr[i]<arr[j]) t[++k]=arr[i++];
		else t[++k]=arr[j++];
	}
	while(i<=mid) t[++k]=arr[i++];
	while(j<=r) t[++k]=arr[j++];
	for(int p=1;p<=k;p++) arr[p+l-1]=t[p];
}
void mergesort(int l,int r,int arr[])
{
	if(l<r)
	{
		int mid=(l+r)>>1;
		mergesort(l,mid,arr);
		mergesort(mid+1,r,arr);
		merge(l,mid,r,arr);
	}
}


猜你喜欢

转载自blog.csdn.net/lyp_1020k/article/details/80068900