数组元素的逆序数

求一个N个元素的逆序数

例如:{1,5,2,6,3}的逆序数为:0+2+0+1+0=3

最直接的求解逆序数方法时间复杂度为O(N^2)

如果用分治的策略可以将时间复杂度降为O(N*logN),求N个元素的逆序数的分治思想如下:首先求前N/2个元素的逆序数,再求后N/2个

元素的逆序数,最后在排序过程中合并前后两部分之间的逆序数

实现代码如下:

#include<iostream>
using namespace std;
int invalid_input=false;
int cal_reverse(int *data,int len,int start,int end);
int merge_reverse(int *data,int len,int start,int mid,int end);
int main()
{
	int n;
	cin>>n;
	int *data=new int[n];
	int i;
	for(i=0;i<n;i++)
		cin>>data[i];
	int num=cal_reverse(data,n,0,n-1);
	if(!invalid_input)
		cout<<num<<endl;
	else
		cout<<"invalid input!"<<endl;
	delete []data;
	return 0;
}
int cal_reverse(int *data,int len,int start,int end)
{
	if(data==NULL||len<=0||start>end)
	{
		invalid_input=true;
		return 0;
	}
	if(start==end)
		return 0;
	else
	{
		int mid=(start+end)>>1;
		int leftnum=cal_reverse(data,len,start,mid);
		int rightnum=cal_reverse(data,len,mid+1,end);
		int mergenum=merge_reverse(data,len,start,mid,end);
		return leftnum+rightnum+mergenum;
	}
}
int merge_reverse(int *data,int len,int start,int mid,int end)
{
	int *temp=new int[len];
	int i=start,j=mid+1,k=start,count=0;
	while(i<=mid&&j<=end)
	{
		if(data[i]>data[j])
		{
			count=count+mid-i+1;
			temp[k++]=data[j];
			j++;
		}
		else
		{
			temp[k++]=data[i];
			i++;
		}
	}
	while(i<=mid)
	{
		temp[k++]=data[i];
		i++;
	}
	while(j<=end)
	{
		temp[k++]=data[j];
		j++;
	}
	for(i=start;i<=end;i++)
		data[i]=temp[i];
	delete []temp;
	return count;
}


原文地址:https://www.cnblogs.com/pangblog/p/3303878.html