数组中逆序对的数量是同运行插入排序产生的移动的数量是相同的,但是选择排序的最差的时间复杂度是n的平方次,但是合并排序最差的是nlogn的时间复杂度。所以应该修改合并排序来计算逆序对数量。在L和R合并的过程中,如果没有移动的话,序列是L+R,所以计算移动的数量就是元素没有移动过R与L与R合并后的位置之间的差值就是移动的数量。
以下代码是实现的算法:
- #include<iostream>
- constintMAXINT=0xFFFF-1;
- voidInversionMerge(intA[],intstart,intmid,intend,int&c)
- {
- intlen1=mid-start+1+1;//加一个位置用于保存哨兵
- intlen2=end-mid+1;//加一个位置用于保存哨兵
- int*L=newint[len1];
- int*R=newint[len2];
- for(inti=0;i<len1-1;i++)
- L[i]=A[start+i];
- L[len1-1]=MAXINT;
- for(intj=0;j<len2-1;j++)
- R[j]=A[mid+j+1];
- R[len2-1]=MAXINT;
- i=0;j=0;
- for(intk=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++;
- }
- }
- }
- voidInversionMergeSort(intA[],intstart,intend,int&c)
- {
- if(start<end)
- {
- intmid=(end+start)/2;
- InversionMergeSort(A,start,mid,c);
- InversionMergeSort(A,mid+1,end,c);
- InversionMerge(A,start,mid,end,c);
- }
- }
- intmain(void)
- {
- int*a;
- intc=0;//保存逆序对数量
- intn;
- std::cout<<"Pleaseinputthearray'ssize:/n";
- std::cin>>n;
- a=newint[n];
- std::cout<<"Pleaseinputthearray'value:"<<std::endl;
- for(inti=0;i<n;i++)
- std::cin>>a[i];
- InversionMergeSort(a,0,n-1,c);
- std::cout<<"Thesortednumberseries:";
- for(i=0;i<n;i++)
- std::cout<<""<<a[i];
- std::cout<<std::endl;
- std::cout<<"theInversionNumberIs"<<c<<std::endl;
- return0;
- }
答案经检验是正确的,开心!