// 对一个数组,求其逆序数。采用归并的求法,复杂度为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)); }