数组中逆序对

// 对一个数组,求其逆序数。采用归并的求法,复杂度为0(nlgn)
#include <cstdio>

bool g_InvalidInput = false;

int InversePairsCore( int *data, int *copy, int first, int last )
{
	if ( first < last )
	{
		int m = first + (last - first)/2;
		int ret = 0;
		ret += InversePairsCore( data, copy, first, m );
		ret += InversePairsCore( data, copy, m+1, last );
    // first first +1 .... m   |   m+1, m+2,.... last-1, last
    //           left      |               right         |
    //                     i                             j
    //      前半部分的逆序数和后部分的逆序数都已经求出
    //      现在要将前半和后半两部分合并起来,求得合并后的逆序数
    //      此处假设每一部分的都是已经排序好的了
    // 初始化i为前半部分最后一个 left
		int i, j, k;
		for ( i=m, j=last, k=last; (i>=first) && (j>=m+1); )
		{
			if ( data[i] > data[j] )
			{
				ret += j - m;
				copy[k--] = data[i--];
			}
			else
				copy[k--] = data[j--];
		
		}
		while( i >= first ) copy[k--] = data[i--];
			
		while ( j >= m+1 ) copy[k--] = data[j--];
			
		for ( int i=first; i<=last; ++i )
			data[i] = copy[i];

		return ret;
	}
	return 0;
}

int InversePairs( int *data, int length )
{
	g_InvalidInput = false;
	if ( data == NULL || length <= 0 )
		return 0;

	int *copy = new int[length];

	int num = InversePairsCore( data, copy, 0, length-1 );

	delete[] copy;

	g_InvalidInput = true;
	return num;
}

int main()
{
	//int data[] = {1, 2, 3, 4, 7, 6, 5}; //3
	//int data[] = {6, 5, 4, 3, 2, 1};//15
	//int data[] = {1, 2, 3, 4, 5, 6};//0
	//int data[] = {1};//0
	int data[] = {1, 2, 1, 2, 1};//3
	int len = sizeof data / sizeof data[0];

	printf("%d\n", InversePairs(data, len));
}

你可能感兴趣的:(数组中逆序对)