您的位置:首页 > 其它

统计数组中的逆序对

2013-06-19 10:29 316 查看
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

分析:借鉴归并排序的思想。

#include <stdio.h>

int find_core(int *a, int *b, int start, int end)
{
if(start == end)
return 0;
int mid = (start+end)/2;
int left = find_core(a,b,start,mid);
int right = find_core(a,b,mid+1,end);
int i = mid;
int j = end;
int k = end;
int temp;//temp用于存储打印逆序对时的j值
int count = 0;//记录逆序对的个数
while(i>=start && j>=mid+1)
{
if(a[i] > a[j])//只有前面数组的元素大于后面数组的元素才算是逆序对
{
temp = j;//记录当前的j值,为了打印逆序对
while(temp>=mid+1)//因为后面数组是由小到大排序好的,所以a[i]>a[j],也代表a[i]大于后面数组中a[j]前面所有的数,直到a[mid+1]
{
printf("%d  %d\n",a[i],a[temp]);
temp--;
}
b[k--] = a[i--];//当前值缓存到辅助数组,用于排序
count += j - (mid+1) + 1;//记录逆序对个数,a[i]和a[j]到a[i]和a[mid+1]都属于逆序对
}
else//如果后面数组元素大于等于前面数组元素,则不是逆序对
{
b[k--] = a[j--];
}
}
while(i>=start)
b[k--] = a[i--];
while(j>=mid+1)
b[k--] = a[j--];
for(i=start;i<=end;i++)
a[i] = b[i];
return left + right + count;//left是前面数组内部统计的逆序对,right是后面数组内部统计的逆序对,count是两个数组之间统计的逆序对,所以不会存在重复问题
}

int find(int *a, int *b, int len)
{
if(a==NULL || b==NULL || len<=0)
return 0;
int count = find_core(a,b,0,len-1);
return count;
}

int main()
{
int a[] = {7,5,6,4};
int len = sizeof(a)/sizeof(int);
int i;
printf("数组为:\n");
for(i=0;i<len;i++)
printf("%d\t",a[i]);
printf("\n");
int *b = new int[len];
printf("逆序对为:\n");
int count = find(a,b,len);
printf("共存在%d对逆序对\n",count);
delete [] b;
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: