给定一个整数数组 A=(a0,a1,…an-1),若 i<j 且 ai>aj,则<ai,aj>就为一 个逆序对。例如数组(3,1,4,5,2)的逆序对有<3,1>,<3,2>,<4,2>, <5,2>。设计一个算法采用蛮力法求 A 中逆序对的个数即逆序数。设计算法求 解逆序对的个数; 需要c语言代码
时间: 2024-02-26 17:58:11 浏览: 109
1.给出一个整数数组,求其中任意两个元素之差的最大值。
5星 · 资源好评率100%
以下是使用归并排序统计逆序对个数的 C 代码:
```c
#include <stdio.h>
int merge(int arr[], int temp[], int left, int mid, int right) {
int i = left;
int j = mid + 1;
int k = left;
int count = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
count += mid - i + 1;
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (i = left; i <= right; i++) {
arr[i] = temp[i];
}
return count;
}
int merge_sort(int arr[], int temp[], int left, int right) {
int count = 0;
if (left < right) {
int mid = (left + right) / 2;
count += merge_sort(arr, temp, left, mid);
count += merge_sort(arr, temp, mid + 1, right);
count += merge(arr, temp, left, mid, right);
}
return count;
}
int count_inversions(int arr[], int n) {
int temp[n];
return merge_sort(arr, temp, 0, n - 1);
}
int main() {
int arr[] = {3, 1, 4, 5, 2};
int n = sizeof(arr) / sizeof(arr[0]);
int count = count_inversions(arr, n);
printf("%d\n", count); // 输出逆序对的个数
return 0;
}
```
在这个代码中,`merge` 函数用来合并两个有序的子数组,并计算逆序对的个数。具体来说,`merge` 函数维护三个指针 `i`、`j` 和 `k`,分别指向左子数组、右子数组和临时数组的开头,比较 `arr[i]` 和 `arr[j]` 的大小,如果 `arr[i]` <= `arr[j]`,则将 `arr[i]` 放入临时数组中,否则将 `arr[j]` 放入临时数组中,并且此时 `arr[i+1:mid+1]` 中的所有元素都与 `arr[j]` 组成逆序对,计数器加上 `mid - i + 1`。最后,将临时数组中的元素复制回原数组中。
`merge_sort` 函数用来递归排序子数组,并计算逆序对的个数。具体来说,`merge_sort` 函数维护两个指针 `left` 和 `right`,分别指向子数组的开头和结尾,如果 `left < right`,则计算中间位置 `mid`,对左右两个子数组分别进行递归排序,并将排序后的结果合并起来,同时统计逆序对的个数。
在主函数中,我们定义了一个数组 `arr`,并将其传递给 `count_inversions` 函数。最后,我们输出逆序对的个数,即 `count`。
阅读全文