归并排序/逆序数组对问题

来源:互联网 发布:s71200编程软件 中文 编辑:程序博客网 时间:2024/04/29 18:28

题目出自Coursera Stanford 算法课程Week 2的Test :

给定一个乱序的长100000的整数数组A,其元素值分别存放在data.txt的每一行中,各元素互不相等。求数组A中逆序对的数目。要求使用分治算法。

其实解法就是将归并排序实现一遍,在归并(Merge)的时候引入计数器,统计逆序对数目。下面是C++ Code:

#include <stdio.h>#include <vector>#include <iostream>#include <random>#include <fstream>using namespace std;vector<int> d;  //设为全局变量static unsigned long long count = 0;  //计数器template<typename type>void printVector(vector<type>&a){    cout<<"Sorted : "<<endl;    for (int i = 0; i < a.size(); i++)    {        cout << "  " << a[i] << "  " ;    }    cout << endl;}//归并排序template <typename type>void mergeVector(vector<type>&a, int first, int mid, int last, vector<type>&temp)//将两个有序子数列合并{    extern unsigned long long int count;    int i = first, j = mid;//第一段有序    int m = mid + 1, n = last;//第二段有序    int k = 0;    while ((i<=j)&&(m<=n))    {        if (a[i] < a[m])        {            temp[k++] = a[i++];        }        else        {            temp[k++] = a[m++];            count = count +j-i+1;  //只需加入计数器,记录逆序数目        }    }    while (i <= j)        temp[k++] = a[i++];    while (m <= n)        temp[k++] = a[m++];    //cout << k << "  ";    //将排好数据写入原数组    for (i = 0; i < k; i++)    {        a[first+i] = temp[i];  //此时的k并不等于a数组的元素总数,所以为first+i    }    cout << endl;}template<typename type>void mergeSort(vector<type>&a, int first, int last, vector<type>temp){    if (first < last)    {        int mid = (first + last) / 2;        mergeSort(a, first, mid, temp);//递归左边子序列        mergeSort(a, mid + 1, last, temp);//递归右边子序列        mergeVector(a, first, mid, last, temp);//合并子序列    }}//将文本文件中得数据读入vector中,并返回一个vector。void InputData_To_Vector(){    ifstream ReadFile("E:/QT/MergeSort/data.txt");    int number=0;    while (!ReadFile.eof()) //这里要注意,如果data.txt最后一行之后无换行(enter),则不要下面的pop_back()!!!    {        ReadFile >> number;        d.push_back(number);    }    d.pop_back(); //此处要将最后一个数字弹出,是因为上述循环将最后一个数字读取了两次(因为此data文件最后一行为换行符)}int main(){    //vector<int> d{ 80,2,601,20,10,60,5,70};    InputData_To_Vector();//读入数据    cout<<d.size()<<endl;    system("pause");    //检查是否完全读入    vector<int> t(d.size());    //printVector(d);    mergeSort(d, 0, d.size()-1,t);   // printVector(d);    cout << endl << "逆序数目: " << count << endl;    system("pause");    return 0;}