逆序对个数:一个数列,如果左边的数大,右边的数小,则称这两个数为一个逆序对。求出一个数列中有多少个逆序对。
PS:学会画示意图,辅助思考。
假设数组的两段分别有序,借助一个辅助数组来缓存原数组,用归并的思路将元素从辅助数组拷贝回原数组。
#include<iostream>
using namespace std;
int nixu=0;
void merge(int arr[],int p,int mid,int r){
int len=r-p+1;
int helper[len];
//拷贝到辅助空间的相同位置
for(int i=0;i<len;i++){
helper[i]=arr[i];
}
//辅助数组的两个指针
int left=p,right=mid+1;
//原始数组的指针
int current=p;
while(left<=mid&&right<=r){
if(helper[left]<=helper[right]){
arr[current++]=helper[left++];
}
else{ //右边小
arr[current++]=helper[right++];
nixu+=mid-left+1;
}
}
//这样做完后,左边指针可能没到头;右边的没到头也没关系
while(left<=mid){
arr[current]=helper[left];
current++;
left++;
}
}
void sort(int A[],int p,int r){
if(p<r){
int mid=p+((r-p)>>1);
sort(A,p,mid);//对左侧排序
sort(A,mid+1,r);//对右侧排序
merge(A,p,mid,r);//合并
}
}
int main(){
int arr[]={1,7,2,9,3,5,6,8};
int len=8;
sort(arr,0,7);
cout<<nixu;
return 0;
}
结果: