归并排序和逆序数

归并排序通过分治的思想可以在nlogn的时间内完成数组的排序

同时在归并排序的归并过程中,又可以通过排序内部的细节获得原数组的逆序数,见注释

直接上代码了:


void merge(int a[],int start,int len,int size)
{
	int l=0,r=0;
	int mid=start+len/2;
	int lsize=min(len/2+len%2,size-start);  //左边集合的个数
	int rsize=min(len,size-start)-lsize;    //右边集合的个数
	int *al=(int *)malloc(sizeof(int)*(lsize));
	int *ar=(int *)malloc(sizeof(int)*(rsize));
	for(int i=start;i<start+lsize;i++)
	{
		al[i-start]=a[i];
	}
	for(int i=start+lsize;i<start+lsize+rsize;i++)
	{
		ar[i-start-lsize]=a[i];
	}
	int k=0;
	for(k=0;l<lsize&&r<rsize;k++)
	{
		if(al[l]<=ar[r])
		{
			a[start+k]=al[l];
			l++;
		}
		else
		{
			a[start+k]=ar[r];
			ans+=lsize-l;          //此时左边集合还有lsize-l个数没有放,则意味着对于右边集合的第一个数,前面有lsize-l个数比它还要大,故逆序数加上lsize-l
			r++;                 
		}
	}
	if(k<lsize+rsize)
	{
		if(l<lsize)
		{
			for(int i=l;i<lsize;i++)
			{
				a[start+k]=al[i];
				k++;
			}
		}
		else
		{
			for(int i=r;i<rsize;i++)
			{
				a[start+k]=ar[i];
				k++;
			}
		}
	}
	free(ar);
	free(al);
}
void mergesort(int a[],int size)
{
	for(int len=2;len<size*2;len*=2)
	{
		for(int i=0;i<size;i+=len)
		{
			    merge(a,i,len,size);
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值