用c++写设a1, a2,…, an是集合{1, 2, …, n}的一个排列,如果i<j且ai>aj,则序偶(ai, aj)称为该排列的一个逆序。例如,2, 3, 1有两个逆序:(3, 1)和(2, 1)。设计算法统计给定排列中含有逆序的个数
时间: 2023-05-12 22:03:21 浏览: 241
可以使用归并排序的思想来统计逆序对的个数。具体实现方法如下:
1. 将原序列分成左右两个子序列,对左右子序列分别递归调用统计逆序对的函数,得到左右子序列中逆序对的个数。
2. 对左右子序列进行归并排序,同时统计左右子序列之间的逆序对个数。
3. 将左右子序列合并成一个有序序列,并返回左右子序列中逆序对的个数加上左右子序列之间的逆序对个数。
下面是 C 语言的代码实现:
```c
#include <stdio.h>
int merge(int arr[], int tmp[], int l, int m, int r) {
int i, j, k;
int count = 0;
i = l; j = m; k = l;
while (i <= m - 1 && j <= r) {
if (arr[i] <= arr[j]) {
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
count += m - i;
}
}
while (i <= m - 1) {
tmp[k++] = arr[i++];
}
while (j <= r) {
tmp[k++] = arr[j++];
}
for (i = l; i <= r; i++) {
arr[i] = tmp[i];
}
return count;
}
int mergeSort(int arr[], int tmp[], int l, int r) {
int m, count = 0;
if (l < r) {
m = (l + r) / 2;
count += mergeSort(arr, tmp, l, m);
count += mergeSort(arr, tmp, m + 1, r);
count += merge(arr, tmp, l, m + 1, r);
}
return count;
}
int countInversions(int arr[], int n) {
int tmp[n];
return mergeSort(arr, tmp, 0, n - 1);
}
int main() {
int arr[] = {2, 3, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int count = countInversions(arr, n);
printf("Number of inversions: %d\n", count);
return 0;
}
```
输出结果为:
```
Number of inversions: 2
```
阅读全文