给定一个数组N,求其中存在的逆序数对。
逆序数的定义,如果N[i]>N[j](i<j),则为一对逆序数。
求解思路:
1:暴力求解(从第一个元素开始遍历,遇到一个比其小的就记录一下)。
2:分治思想:归并排序的副产物,在Merge()时记录逆序数对。
#include <iostream>
#include <math.h>
using namespace std;
const int NUM=100000;
const char* filepath="E:\\data.txt";
int Mid[NUM]={0};
long long answer=0;
void File_to_Array(int* array)
{
FILE * f;
int idx=0;
if((f=fopen(filepath,"r"))==NULL)
{
cout<<"文件打开失败!"<<endl;
}
else{
while(!feof(f))
{
fscanf(f,"%d",&array[idx]);
idx++;
}
fclose(f);
}
}
void Merge(int* s,int low,int mid,int up)
{
int a=low,b=mid+1;
for(int i=low;i<=up;i++)
Mid[i]=s[i];
for(int i=low;i<=up;i++)
{
if(a>mid)
s[i]=Mid[b++];
else if(b>up)
s[i]=Mid[a++];
else if(Mid[a]<=Mid[b])
s[i]=Mid[a++];
else {
s[i]=Mid[b++];
answer+=mid-a+1;
}
}
}
void Sort(int* s,int low,int up)//归并排序
{
if(up<=low)
return;
else
{
int mid=(low+up)/2;
Sort(s,low,mid);
Sort(s,mid+1,up);
Merge(s,low,mid,up);
}
}
int main()
{
int array[NUM];
File_to_Array(array);
Sort(array,0,NUM-1);
// printf("\n");
// for(int i=0;i<NUM;i++)
// {
// printf("%d ",array[i]);
// }
cout<<answer;
return 0;
}
最重要的一行代码answer+=mid-a+1,合并时当第一个子数组一个元素大于第二个子数组的某个元素时,产生的逆序数对为前一个子数组剩余的元素数。