归并:利用分治思想,对数组进行二分分割
一直分到每部分剩下一个元素,然后左右合并
合并的时候利用一个临时数组比较方便
static void mergeSort(int[]ar,int l,int r)
{
if(l>=r)
return;
int mid=(l+r)/2;
mergeSort(ar,l,mid);
mergeSort(ar,mid+1,r);
int[] temp=new int[r-l+1];
int index=0,begin=l,end=mid+1;
while(begin<=mid && end<=r)
temp[index++]=ar[begin]>ar[end]?ar[end++]:ar[begin++];
while(begin<=mid)
temp[index++]=ar[begin++];
while(end<=r)
temp[index++]=ar[end++];
for(int i=0;i<index;i++)
ar[l+i]=temp[i];
}
逆序对:利用归并排序
sum+=mid-begin+1;
因为 l 到 mid mid+1到 r 是有序的 所以begin到mid的元素都是ar[end]的逆序对
static int sum;
static void f(int l,int r,int []ar)
{
if(l>=r)
return ;
int mid=(l+r)/2;
f(l,mid,ar);
f(mid+1,r,ar);
int []temp=new int[r-l+1];
int index=0,begin=l,end=mid+1;
while(begin<=mid && end<=r)
{
if(ar[begin]>ar[end])
{
sum+=mid-begin+1;
temp[index++]=ar[end++];
}else {
temp[index++]=ar[begin++];
}
}
while(begin<=mid)
temp[index++]=ar[begin++];
while(end<=r)
temp[index++]=ar[end++];
for(int i=0;i<index;i++)
ar[l+i]=temp[i];
}