// 对一个数组,求其逆序数。采用归并的求法,复杂度为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));
}
数组中逆序对
最新推荐文章于 2022-05-24 21:38:41 发布