The attached file Q8.txt contains 100,000 integers between 1 and 100,000 (each row has a single integer), the order of these integers is random and no integer is repeated.
- Write a program to implement the Sort-and-Count algorithms in your favorite language, find the number of inversions in the given file.
- In the lecture, we count the number of inversions in O(nlogn) time, using the Merge-Sort idea. Is it possible to use the Quick-Sort idea instead ?
If possible, implement the algorithm in your favourite language, run it over the given file, and compare its running time with the one above. If not, give a explanation
1. 归并法
最终逆序对的个数是:2500572073
归并法的核心就是通过讲子问题划分成一个一个小的问题后进行合并求解。首先对整个数组一直对半的进行划分,一直分到只剩1个为止开始排序并合并,如上图所示。
具体算法如下。从第74行开始计算将要合并的两个子数组的逆序对数,如果左边数组的的一个值是大于右边数组中的数的,则说明左边数组中这个数的后面所有的数字都是大于右边数组的这个数字的(因为在合并时,左右两边数组都已经是有序的),因此直接加 (mid - left + 1 - i)
就可以了,然后一层一层的向上计算过去,即得到了逆序对数。
因为老师有让对比归并法和快排法的效率,因此中间有计算时间的。
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<sys/time.h>
#include<iostream>
#include<fstream>
#define MAXN 100001
using namespace std;
double SortAndCount(int left, int right);
double MergeAndCount(int left, int mid, int mid1, int right);
//int num[] = {2, 4, 1, 3, 5};
//int num[] = {4, 7, 6, 3, 1, 2, 9, 8, 5};
int num[MAXN];
int main()
{
char n[15];
int i = 0;
double ans;
struct timeval t_start, t_end;
//open the file
ifstream in("Q8.txt", ios::in);
if (!in.is_open()) {
<