C语言实现分治算法给定一个序列a1,a2,…,an,如果存在i < j并且ai > aj,那么我们称之为逆序对,求逆序对的数目 输入:第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。 输出:所有逆序对总数
时间: 2023-12-03 16:45:42 浏览: 246
下面是使用C语言实现分治算法求解逆序对的代码:
```c
#include <stdio.h>
long long merge(int arr[], int temp[], int left, int mid, int right)
{
int i, j, k;
long long count = 0;
i = left;
j = mid;
k = left;
while ((i <= mid - 1) && (j <= right)) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
count += (mid - i);
}
}
while (i <= mid - 1)
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i = left; i <= right; i++)
arr[i] = temp[i];
return count;
}
long long mergeSort(int arr[], int temp[], int left, int right)
{
int mid;
long long count = 0;
if (right > left) {
mid = (right + left) / 2;
count += mergeSort(arr, temp, left, mid);
count += mergeSort(arr, temp, mid + 1, right);
count += merge(arr, temp, left, mid + 1, right);
}
return count;
}
int main()
{
int n, i;
scanf("%d", &n);
int arr[n], temp[n];
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
long long ans = mergeSort(arr, temp, 0, n - 1);
printf("%lld\n", ans);
return 0;
}
```
在这个算法中,我们使用了归并排序的思想。我们将原序列分成两个子序列,分别对它们进行归并排序,并统计逆序对的数量。然后我们将两个子序列合并成一个有序的序列,并继续统计逆序对的数量。最后,我们将得到原序列的有序副本,并且我们也能够得到逆序对的总数。
在归并排序的过程中,我们使用一个临时数组来存储排序结果。在合并两个子序列的过程中,我们比较它们的元素,并将较小的元素复制到临时数组中。当我们复制一个元素时,如果这个元素比另一个子序列中的所有元素都大,那么它能够形成逆序对,并且逆序对的数量就是另一个子序列中剩余的元素数量。
最后,我们返回逆序对的总数。
这个算法的时间复杂度为 O(nlogn),其中 n 是序列的长度。
阅读全文