逆序对


#include<stdio.h>
//直接枚举
int inverse_pair1(int *a, int n)
{
  int count=0;
  int i,j;
  for(i=0;i<n;++i)
    for(j=i+1;j<n;++j)
      if(a[i]>a[j])
	count++;
  return count;
}
//用归并排序的思想,左边的逆序对加右边的加左右之间的总和
int merge(int *a, int left, int right)  //左闭右闭
{
  int mid=(left+right)/2;
  int i,j,k;
  int L[5],R[5];
  int count=0,count_l,count_r;
  if(left>=right)
    return 0;
  count_l=merge(a,left,mid);
  count_r=merge(a,mid+1,right);
  
  i=left;j=mid+1;
  for(k=0;k<mid-left+1;k++)//将数组左边排序结果记录在L中
    L[k]=a[i++];
  for(k=0;k<right-mid;k++)//将数组右边排序结果记录在R中
    R[k]=a[j++];
  i=0;j=0;k=left;
  //归并时记录逆序个数
  while(i<mid-left+1 && j<right-mid){
    if(L[i]<R[j]){
      a[k++]=L[i++];
    }
    else{
      a[k++]=R[j++];
      count+=(mid-left-i+1);  //右边比左边小,左边留下的数与R[j]全为逆序对
    }
  }
  //余下单个数组的处理
  while(i<mid-left+1)
    a[k++]=L[i++];
  while(j<right-mid)
    a[k++]=R[j++];
  //printf("count=%d ",count);
  return count_l+count_r+count;
}
int main(int argc, char *argv[])
{
  int a[]={2,3,8,6,1};
  int b[]={5,4,3,2,1};
  int i=0;
  printf("inverse=%d\n",inverse_pair1(a,5));
  printf("inverse=%d\n",merge(a,0,4));
  for(i=0;i<5;++i)
    printf("%d ",a[i]);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值