在nlgn时间内实现逆序对数的计算

        数组中逆序对的数量是同运行插入排序产生的移动的数量是相同的,但是选择排序的最差的时间复杂度是n的平方次,但是合并排序最差的是nlogn的时间复杂度。所以应该修改合并排序来计算逆序对数量。在L和R合并的过程中,如果没有移动的话,序列是L+R,所以计算移动的数量就是元素没有移动过R与L与R合并后的位置之间的差值就是移动的数量。

        以下代码是实现的算法:

  1. #include <iostream>
  2. const int MAXINT=0xFFFF-1;
  3. void InversionMerge(int A[], int start, int mid, int end,int &c)
  4. {
  5.     int len1 = mid-start+1+1;//加一个位置用于保存哨兵
  6.     int len2 = end-mid+1;//加一个位置用于保存哨兵
  7.     int *L =new int[len1];
  8.     int *R =new int[len2];
  9.     for(int i=0;i<len1-1;i++)
  10.         L[i]=A[start+i];
  11.     L[len1-1]=MAXINT;
  12.     for(int j=0;j<len2-1;j++)
  13.         R[j]=A[mid+j+1];
  14.     R[len2-1]=MAXINT;
  15.     i=0;j=0;
  16.     for(int k=start;k<=end;k++)
  17.     {
  18.         if(L[i]<=R[j])
  19.         {
  20.             A[k]=L[i];
  21.             i++;
  22.         }
  23.         else
  24.         {
  25.             A[k]=R[j];
  26.             c=c+((mid+1+j)-k);
  27.             j++;
  28.         }
  29.     }
  30. }
  31. void InversionMergeSort(int A[], int start, int end,int &c)
  32. {
  33.     if(start<end)
  34.     {
  35.         int mid = (end +start)/2;
  36.         InversionMergeSort(A,start,mid,c);
  37.         InversionMergeSort(A,mid+1,end,c);
  38.         InversionMerge(A,start,mid,end,c);
  39.     }
  40. }
  41. int main(void)
  42. {
  43.     int *a;
  44.     int c=0;//保存逆序对数量
  45.     int n;
  46.     std::cout<<"Please input the array's size: /n";
  47.     std::cin>>n;
  48.     a=new int[n];
  49.     std::cout<<"Please input the array' value: "<<std::endl;
  50.     for(int i=0;i<n;i++)
  51.         std::cin>>a[i];
  52.     InversionMergeSort(a,0,n-1,c);
  53.     std::cout<<"The sorted number series: ";
  54.     for(i=0;i<n;i++)
  55.         std::cout<<" "<<a[i];
  56.     std::cout<<std::endl;
  57.     std::cout<<"the Inversion Number Is "<<c<<std::endl;
  58.     return 0;
  59. }

答案经检验是正确的,开心!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值