C++计算逆序对

来源:互联网 发布:dns默认端口 编辑:程序博客网 时间:2024/05/27 10:43
转自:http://blog.csdn.net/forget_me_not1991/article/details/40394225

网上有很多关于逆序对的计算方法及源代码,我仅仅在这里记录下自己的理解

逆序对:设a[0…n]为包含n个不数的一个序列,如果n<m,且a[n]>a[m],则称(n,m)构成a中的一个逆序对;

问题:给出一个数字序列,找出其逆序对的个数;


解答:

本文主要介绍采用归并排序算法计算逆序对;

主要思想为将数组分成两份,这样所有的逆序对由三部分组成:1.前半部分的逆序对;2.后半部分的逆序对;3.前后两部分之间的逆序对;

然后1,2中的逆序对可以分解为本问题的一个子问题,适合采用递归求解;源代码如下:

#include <iostream>  #include <vector>  using namespace std;  int countReversed(vector<int> &a, int begin,int end);  int merge(vector<int> &a, int begin, int mid, int end);  int main()  {      vector<int> arr;      int num = 0;      int count;      cout << "input the number of data " << endl;      cin >> count;      cout << "input data :" << endl;      for (int i = 0; i < count; ++i)      {          cin >> num;          arr.push_back(num);      }      cout << "result is : " << countReversed(arr, 0, arr.size() - 1) << endl;      getchar();      return 0;  }  int countReversed(vector<int> &a, int begin,int end)  {      if (begin < end)      {          int mid = (begin + end) / 2;          return (countReversed(a, begin, mid) +              countReversed(a, mid + 1, end) + merge(a, begin, mid, end));      }      else      {          return 0;      }  }  //计算前后之间逆序对的个数,因为这部分在计算完数组前半部分逆序数和后  //半部分逆序数之后计算,所以在计算两部分之间的逆序对的同时,对数组进行  //归并排序  int merge(vector<int> &a, int begin, int mid, int end)  {      int nCount = 0; //前后两段之间逆序的个数      vector<int >b;      int j = begin, k = mid + 1;      int n = end - begin + 1;      int i = 0;      for (i = 0; i < n ; ++i)      {          if (j > mid || k > end)          {              break;          }          if (a.at(j) <= a.at(k))          {              b.push_back(a.at(j));              ++j;          }          else          {              b.push_back(a.at(k));              nCount += mid - j + 1;              ++k;          }      }      while (j <= mid)      {          b.push_back(a.at(j));          ++j;      }      while (k <= end)      {          b.push_back(a.at(k));          ++k;      }      for (i = 0; i < n; ++i)      {          a[begin + i] = b[i];      }      return nCount;  }  
原创粉丝点击