逆序对的递归求法

来源:互联网 发布:舞台灯c语言程序下载 编辑:程序博客网 时间:2024/05/21 10:02
int cnt=0;// 逆序对个数int a[100002], c[100002];void MergeSort(int l, int r)// r=右边界索引+1{ int mid, i, j, tmp;if (r>l+1){mid = (l+r)/2;MergeSort(l, mid);MergeSort(mid, r);tmp = l;for (i=l,j=mid; i<mid && j<r; ){if (a[i]>a[j]){c[tmp] = a[j];tep++,j++;cnt += mid-i;// 使用排序,就可以方便地数跨“分界”的逆序对个数了}elsec[tmp++] = a[i++];}if (j<r) for (; j<r; j++) c[tmp++] = a[j];else for (; i<mid; i++) c[tmp++] = a[i];for (i=l; i<r; i++) a[i]=c[i];}}


 

#include<iostream>using namespace std; /* 归并求逆序对数, arr 存储最终有序结果 * 在函数外申请一个临时数组作为参数传入 * 避免递归不断创建临时数组的开销 */int Merge(int * arr, int beg, int mid, int end, int * tmp_arr){    memcpy(tmp_arr+beg,arr+beg,sizeof(int)*(end-beg+1));    int i = beg;    int j = mid + 1;    int k = beg;    int inversion = 0;  // 合并过程中的逆序数    while(i <= mid && j <= end)    {        if(tmp_arr[i] <= tmp_arr[j])        {            arr[k++] = tmp_arr[i++];        }else        {            arr[k++] = tmp_arr[j++];            inversion += (mid - i + 1);        }    }    while(i <= mid)    {        arr[k++] = tmp_arr[i++];    }    while(j <= end)    {        arr[k++] = tmp_arr[j++];    }    return inversion;} int MergeInversion(int * arr, int beg, int end, int * tmp_arr){    int inversions = 0;    // 记录倒序数    if(beg < end)    {        int mid = (beg + end) >> 1;        inversions += MergeInversion(arr, beg, mid, tmp_arr);        inversions += MergeInversion(arr, mid+1, end, tmp_arr);        inversions += Merge(arr, beg, mid, end, tmp_arr);    }    return inversions;} /* 测试序列 :answer: 10 */int testPoint[10] = {    1, 4, 2, 9, 48,   15, 13, 44, 6, 90}; void main(){    int arrcopy[10];      // 临时数组    memcpy(arrcopy,testPoint,sizeof testPoint);     printf("the num of inversions is: %d\n",            MergeInversion(testPoint,0,9,arrcopy));}


0 0
原创粉丝点击