• 归并排序和逆序数


    归并排序通过分治的思想可以在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);
    		}
    	}
    }




  • 相关阅读:
    正则表达式
    查看当前文件大小
    logging日志快速上手
    kafka消息队列的使用
    修改文件权限给指定的用户
    使用Dockerfile构建镜像
    k8s 常用命令总结
    k8s pod.yaml配置文件参数
    Linux安装依赖包
    Freeswitch配置SIP网关拨打外部
  • 原文地址:https://www.cnblogs.com/oneshot/p/3979876.html
Copyright © 2020-2023  润新知