归并排序-逆序对数
2015-04-01 22:27
399 查看
/*
程序装载自:http://www.cnblogs.com/XiongHarry/archive/2008/11/06/1327732.html
求逆序对数
设A[1..n]是一个包含N个非负整数的数组。如果在i〈 j的情况下,有A〉A[j],则(i,j)就称为A中的一个逆序对。
例如,数组(3,1,4,5,2)的“逆序对”有<3,1>,<3,2><4,2><5,2>,共4个。
使用归并排序可以用O(nlogn)的时间解决统计逆序对个数的问题
定义:对于一个给定的数列,如果有i<j,且Ai>Aj,则称(i,j)为一逆序对.
要解决的问题是,给出一个数列,求出这个数列包含多少个逆序对
问题解析:
如何把逆序从问题中抽象出来成为解决问题的关键,这里的 逆序对数 实际就是插入排序中从后往前查时元素移动的次数,
也就是有序的序列逆序对数为0,
最简单的算法就是 类似冒泡一样从第一个位置开始向后比较,比较完在从第二个比较,这样的时间复杂度为 n^2;
如果利用归并的思想来编程序,时间复杂度为 nLog( n );
那么如何用到归并排序的思想呢?如果用归并,那么归并 和 冒泡 相比又有那些优势?
*/
未完待续
程序装载自:http://www.cnblogs.com/XiongHarry/archive/2008/11/06/1327732.html
求逆序对数
设A[1..n]是一个包含N个非负整数的数组。如果在i〈 j的情况下,有A〉A[j],则(i,j)就称为A中的一个逆序对。
例如,数组(3,1,4,5,2)的“逆序对”有<3,1>,<3,2><4,2><5,2>,共4个。
使用归并排序可以用O(nlogn)的时间解决统计逆序对个数的问题
定义:对于一个给定的数列,如果有i<j,且Ai>Aj,则称(i,j)为一逆序对.
要解决的问题是,给出一个数列,求出这个数列包含多少个逆序对
问题解析:
如何把逆序从问题中抽象出来成为解决问题的关键,这里的 逆序对数 实际就是插入排序中从后往前查时元素移动的次数,
也就是有序的序列逆序对数为0,
最简单的算法就是 类似冒泡一样从第一个位置开始向后比较,比较完在从第二个比较,这样的时间复杂度为 n^2;
如果利用归并的思想来编程序,时间复杂度为 nLog( n );
那么如何用到归并排序的思想呢?如果用归并,那么归并 和 冒泡 相比又有那些优势?
*/
#include <iostream> #include <vector> using namespace std; //普通法查找逆序对 普通实现 O(n^2): template<class Iterator> int CountInversePair(Iterator first ,Iterator last) { Iterator it ,it2; int count = 0; for(it= first ;it!=last-1;++it) { for(it2=it+1;it2!=last;++it2) { if(*it>*it2) count ++; } } return count; } //归并法查找逆序对 int gCount = 0; template<class Iterator> int merge(Iterator begin, Iterator mid, Iterator end) { Iterator iL = begin; Iterator iR = mid; int count = distance(begin, end); vector<int> v(count); vector<int>::iterator it = v.begin(); while(iL != mid && iR != end) { if(*iL <= *iR){ *it++ = *iL++; }else{ gCount += distance(iL, mid); *it++ = *iR++; } } if(iL == mid) copy(iR, end, it); if(iR == end) copy(iL, mid, it); copy(v.begin(), v.end(), begin); return 0; } template<class Iterator> int mergeSort(Iterator begin, Iterator end) { int count, step; count = distance(begin, end); if(count <= 1){ return 0; } step = count / 2; mergeSort(begin, begin + step); mergeSort(begin + step, end); merge(begin, begin + step, end); return 0; } int main() { int line[] = {3,1,4,5,2}; //cout << CountInversePair(line,line+sizeof(line)/sizeof(int)) << endl; mergeSort(line,line+sizeof(line)/sizeof(int)) ; cout << gCount << endl; return 0; }
未完待续
相关文章推荐
- 【java】归并排序 逆序对数
- 求逆序对数的NLogN解法:归并排序、树状数组和线段树
- 算法1:求逆序对数与显著逆序对数(归并排序)
- 归并排序求逆序对数
- 百练2299:Ultra-QuickSort(归并排序求逆序对数)
- 51nod1107(逆序对数&归并排序)
- 归并排序求逆序对数
- Ultra-QuickSort(归并排序求逆序对数)
- 归并排序求 逆序对数 TOJ 1455 Ultra-QuickSort
- 关于归并排序及快速求序列逆序对数的学习
- POJ2299——归并排序求逆序对数
- POJ 1804 Brainman (归并排序 -- 求逆序对数)
- 求逆序对数的NLogN解法:归并排序、树状数组和线段树
- 紫书第八章-----高效算法设计(归并排序求逆序对数)
- 求逆序对数的方法(归并排序 and 树状数组)
- 归并排序及利用归并排序求逆序对数
- 求逆序对数总结 & 归并排序
- 逆序对数(归并排序)
- ACM:归并排序,以及利用归并排序思想求解逆序对数!
- 归并排序求逆序对数