用C语言写出利用分治法计算整数序列x1,x2,...x 中逆序对个数的程序,注释清楚程序中每个变量的含义。
时间: 2024-11-05 16:30:34 浏览: 41
分治法-大整数相乘.docx
以下是使用 C 语言编写的一个基于分治法计算整数序列中逆序对的简单程序。在这个例子中,我们假设数组 `arr` 存储了序列 `x1, x2, ..., xn` 的元素。`countInversions` 函数实现了快速排序并计算逆序对的数量。
```c
#include <stdio.h>
// 分治法函数 - 快速排序并计算逆序对
int countInversions(int arr[], int left, int right) {
// Base case: 如果只有一个元素或没有元素,不存在逆序对
if (left == right)
return 0;
// 找到中间点
int mid = (left + right) / 2;
// 计算左半部分的逆序对数
int inversions_left = countInversions(arr, left, mid);
// 计算右半部分的逆序对数
int inversions_right = countInversions(arr, mid + 1, right);
// 递归合并,计算跨过中间点的逆序对数
int inversions_cross = mergeAndCountInversions(arr, left, mid, right);
// 返回所有部分的逆序对总数
return inversions_left + inversions_right + inversions_cross;
}
// 合并两个已排序的部分,并统计跨越它们之间的逆序对
int mergeAndCountInversions(int arr[], int left, int mid, int right) {
int i = left; // 左指针
int j = mid + 1; // 右指针
int temp[right - left + 1]; // 中间结果数组
int inversions = 0; // 用于记录逆序对
for (int k = 0; k <= right - left; k++) {
// 当左边还有元素并且右边的元素大于左边的元素时,计数逆序对
if (i <= mid && (j > right || arr[i] <= arr[j])) {
temp[k] = arr[i];
i++;
} else {
temp[k] = arr[j];
j++;
// 如果arr[i]小于arr[j],说明逆序,增加逆序对计数
inversions += mid - i + 1;
}
}
// 将临时数组的内容复制回原数组
for (int k = 0; k <= right - left; k++)
arr[left + k] = temp[k];
return inversions;
}
int main() {
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
int arr[n];
printf("Enter the sequence of numbers: ");
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
int inversion_count = countInversions(arr, 0, n - 1);
printf("The number of inversions is: %d\n", inversion_count);
return 0;
}
```
阅读全文