1.思路:分治法
划分问题:分成尽量相等的两半;递归求解:统计i,j分别在左右时的逆序对个数;
合并:统计i在左边,j在右边的逆序对数
-->只需统计对右边的每个j,左边比他大的元素个数F(j)即可
-->所有F(j)之和即为逆序对的个数
-->递归排序按从小到大的顺序排列的过程中,将右边的元素复制到临时数组中时,说明左边剩余元素的个数都比A[j]大,即m-p个,用一个全局变量累加起来即可
栈溢出问题:当n的数量级大于10^6,会发生栈溢出,所以要动态分配内存到堆中
#include<stdio.h>
#define MAX 1000000
int cnt=0;
void merge_sort(int *A,int x,int y,int *T)
{
if(y-x>1)
{
int i,m,p,q;
m=x+(y-x)/2;
p=x;q=m;i=x;
merge_sort(A,x,m,T);
merge_sort(A,m,y,T);
while(p<m||q<y)
{
if(q>=y || (p<m&&A[p]<=A[q]))
T[i++]=A[p++];
else
{
T[i++]=A[q++];
cnt+=m-p;
}
}
for(i=x;i<y;i++)
A[i]=T[i];
}
}
int main()
{
int i;
int A[8]={13,7,20,2,11,9,12,1};
int *T=(int*)malloc(MAX*sizeof(int));
merge_sort(A,0,8,T);
free(T);
for(i=0;i<8;i++)
printf("%d ",A[i]);
printf("\n%d\n",cnt);
return 0;
}
栈溢出问题:当n的数量级大于10^6,会发生栈溢出,所以要动态分配内存到堆中