如何使用归并排序计算大量输入的反转次数
Posted
技术标签:
【中文标题】如何使用归并排序计算大量输入的反转次数【英文标题】:How to count number of inversions for large number of inputs using merge sort 【发布时间】:2020-01-27 08:36:59 【问题描述】:我能够计算少量输入的反转。我应该进行哪些更改来计算 100000 个输入的反转次数。
#include<iostream>
using namespace std;
int _mergeSort(int arr[], int temp[], int left, int right);
int merge(int arr[], int temp[], int left, int mid, int right);
int mergeSort(int arr[], int array_size)
int temp[array_size];
return _mergeSort(arr, temp, 0, array_size - 1);
int _mergeSort(int arr[], int temp[], int left, int right)
int mid, inv_count = 0;
if (right > left)
/*Divide the array into two parts
and call _mergeSortAndCountInv()
for each of the parts*/
mid = (left + right) / 2;
/*Inversion count will be sum of inversions in left-part
right-part as well as number of inversions while merging */
inv_count = _mergeSort(arr, temp, left, mid); // counting inversions in the left part
inv_count += _mergeSort(arr, temp, mid + 1, right); //counting inversions in the right part
inv_count += merge(arr, temp, left, mid + 1, right);
return inv_count;
int merge(int arr[], int temp[], int left, int mid, int right)
int i, j, k;
int inv_count = 0;
i = left; // i is the index for left subarray
j = mid; // j is the index for right subarray
k = right; // k is the index for resultant merged subarray
while (i <= (mid - 1) && j <= right)
if (arr[i] < arr[j])
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
// copying the remaining parts of the left subarray to temp (if any)
while (i <= (mid - 1))
temp[k++] = arr[i++];
// copying the remaining parts of the left subarray to temp (if any)
while (j <= right)
temp[k++] = arr[j++];
// copying back the merged elements to oroginal array ;
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
int main()
int arr[] = 5, 7, 2, 3, 9, 1 ;
int n = sizeof(arr) / sizeof(arr[0]);
int ans = mergeSort(arr, n);
cout << "Number of inversions are" << "\n" << ans;
return 0;
【问题讨论】:
如果您的基于归并排序的例程正常工作小输入,它也能够处理任何可能大小(亿)的输入 【参考方案1】:k = 对; // k 是结果合并子数组的索引
这行有问题我猜应该是
k=左;
所以问题出在排序算法上。 合并排序的时间复杂度是 Nlog(N) 而你添加的只是一行
inv_count = inv_count + (mid - i);
恒定复杂度因此它不会改变算法的整体复杂度。即使输入是100000,计算数组中的反转次数也不会有任何问题。
【讨论】:
以上是关于如何使用归并排序计算大量输入的反转次数的主要内容,如果未能解决你的问题,请参考以下文章