数组中逆序对的数量是同运行插入排序产生的移动的数量是相同的,但是选择排序的最差的时间复杂度是n的平方次,但是合并排序最差的是nlogn的时间复杂度。所以应该修改合并排序来计算逆序对数量。在L和R合并的过程中,如果没有移动的话,序列是L+R,所以计算移动的数量就是元素没有移动过R与L与R合并后的位置之间的差值就是移动的数量。
以下代码是实现的算法:
- #include <iostream>
- const int MAXINT=0xFFFF-1;
- void InversionMerge(int A[], int start, int mid, int end,int &c)
- {
- int len1 = mid-start+1+1;//加一个位置用于保存哨兵
- int len2 = end-mid+1;//加一个位置用于保存哨兵
- int *L =new int[len1];
- int *R =new int[len2];
- for(int i=0;i<len1-1;i++)
- L[i]=A[start+i];
- L[len1-1]=MAXINT;
- for(int j=0;j<len2-1;j++)
- R[j]=A[mid+j+1];
- R[len2-1]=MAXINT;
- i=0;j=0;
- for(int k=start;k<=end;k++)
- {
- if(L[i]<=R[j])
- {
- A[k]=L[i];
- i++;
- }
- else
- {
- A[k]=R[j];
- c=c+((mid+1+j)-k);
- j++;
- }
- }
- }
- void InversionMergeSort(int A[], int start, int end,int &c)
- {
- if(start<end)
- {
- int mid = (end +start)/2;
- InversionMergeSort(A,start,mid,c);
- InversionMergeSort(A,mid+1,end,c);
- InversionMerge(A,start,mid,end,c);
- }
- }
- int main(void)
- {
- int *a;
- int c=0;//保存逆序对数量
- int n;
- std::cout<<"Please input the array's size: /n";
- std::cin>>n;
- a=new int[n];
- std::cout<<"Please input the array' value: "<<std::endl;
- for(int i=0;i<n;i++)
- std::cin>>a[i];
- InversionMergeSort(a,0,n-1,c);
- std::cout<<"The sorted number series: ";
- for(i=0;i<n;i++)
- std::cout<<" "<<a[i];
- std::cout<<std::endl;
- std::cout<<"the Inversion Number Is "<<c<<std::endl;
- return 0;
- }
答案经检验是正确的,开心!