利用分治法实现逆序数对的求解

给定一个数组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,合并时当第一个子数组一个元素大于第二个子数组的某个元素时,产生的逆序数对为前一个子数组剩余的元素数。

点赞