归并排序(合并排序)
来源:互联网 发布:淘宝店铺怎么铺货 编辑:程序博客网 时间:2024/05/16 16:57
/**题目:要求冒泡排序的交换次数,也就是求逆序数的个数。在一个排列中如果有两个数的排序和所规定的排序规则相反,则这两个数是一个逆序。一个排列中的逆序的总数就是这个排列的逆序数。用归并排序,求逆序数的个数。##Poj 2299 这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在**/#include <cstdio>int left[250003], right[250003];long long count;void merge(int a[], int l, int m, int r){ int i, j, k, n1, n2; n1 = m - l + 1; n2 = r - m; for (i = 0; i < n1; i++) left[i] = a[l+i]; for (i = 0; i < n2; i++) right[i] = a[m+i+1]; left[n1] = right[n2] = 0x7fffffff; i = j = 0; for (k = l; k <= r; k++) { if (left[i] <= right[j]) { a[k] = left[i++]; } else { a[k] = right[j++]; count += n1 - i; // 此步骤是在归并排序法中加的一句,用来计数求逆序数的数目 } }}void mergeSort(int a[], int l, int r){ if (l < r) { int m = (l + r) / 2; mergeSort(a, l, m); mergeSort(a, m+1, r); merge(a, l, m, r); }}int main(){ int n, a[500001]; while (scanf("%d", &n) && n) { count = 0; for (int i = 0; i < n; i++) scanf("%d", &a[i]); mergeSort(a, 0, n-1); printf("%lld\n", count); }}