归并排序求逆序对

来源:互联网 发布:安居客网络经纪人平台 编辑:程序博客网 时间:2024/06/05 01:59

给定数组 如{5,8,3,1}   则有<5,3><5,1><8,3><8,1><3,1> 5个逆序对 

给定数组 求其逆序对的个数

思路:归并排序   O(NlogN) 时间复杂度   O(N) 空间复杂度

如上图:在两个有序的子序列中。 arr[p] > arr[q] && p < q; 满足逆序对的条件。此时,和arr[q]互为逆序对的元素有mid-p+1个。

复制代码
#include <iostream> using namespace std;int d = 0;void mergerArray(int p, int mid, int q, int start, int end, int arr[], int T[]){    int i = start;    while(p<=mid && q<=end){        if(arr[p] <= arr[q])            T[i++] = arr[p++];        else{              T[i++] = arr[q++];            d += mid - p + 1; //发生逆序,此时由于            //arr[p..mid]是已经有序了,那么arr[i+1], arr[i+2], ... arr[mid]都是大于arr[q]的,            //都可以和a[q]组成逆序对,因此number += mid - q + 1        }    }    while(p<=mid){        T[i++] = arr[p++];    }    while(q<=end){        T[i++] = arr[q++];    }    for(i=start; i<=end;i++){        arr[i] = T[i];    }}void mergerSort(int arr[], int start, int end, int T[]){    if(end>start){        int mid = (end+start)/2;        int p = start;        int q = mid + 1;        mergerSort(arr, start, mid , T);        mergerSort(arr, mid+1, end, T);        mergerArray(p, mid, q, start, end, arr, T);    }}int main(){    int n;    int arr[1000];    int T[1000];    while(cin>>n){        for(int i=0;i<n;i++){            cin >> arr[i];        }        mergerSort(arr, 0, n-1, T);        for(int i=0;i<n;i++){            cout << arr[i] << " " ;        }cout<<endl;                cout << "d=" << d << endl;    }}
复制代码
0 0
原创粉丝点击