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

题目出自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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值