归并排序(合并排序)

/**
题目:要求冒泡排序的交换次数,也就是求逆序数的个数。
在一个排列中如果有两个数的排序和所规定的排序规则相反,则这两个数是一个逆序。
一个排列中的逆序的总数就是这个排列的逆序数。
用归并排序,求逆序数的个数。

##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);
    }
}

你可能感兴趣的:(merge,n2)