归并排序

       学了几天的排序,我们也该把注意力转移到归并排序身上了,归并排序以O(N*logN)最坏情形运行时间运行,而其所用的比较次数几乎是最优的。

       归并排序采用了最基本的分治(divide-and-conquer)策略,它将问题分成一些小的问题然后递归求解,再将各个阶段的答案修补到一起,首先我们来看一下归并排序最基本的归并过程,递归是依赖于这个归并过程的,代码如下:

void Merge(int a[],int tmp[],int Lpos,int Rpos,int RightEnd)//归并的过程
{
	int i,leftend,num,tmpos;
	leftend=Rpos-1;
	tmpos=Lpos;//暂时的位置,从左开始
	num=RightEnd-Lpos+1;//要排序的数目
	while(Lpos<=leftend&&Rpos<=RightEnd)
	{
		if(a[Lpos]<=a[Rpos])
			tmp[tmpos++]=a[Lpos++];
		else
			tmp[tmpos++]=a[Rpos++];
	}
	while(Lpos<=leftend)
		tmp[tmpos++]=a[Lpos++];
	while(Rpos<=RightEnd)
		tmp[tmpos++]=a[Rpos++];
	for(i=0;i<num;i++,RightEnd--)
		a[RightEnd]=tmp[RightEnd];//现在整个tmp都是有序的,把值全部赋给a
}
       Merge过程把每次排序好的先放到一个临时数组中,最后再把该数组的值赋给主数组。

       下面就是归并排序的递归过程了,它把问题分成两大块,左半部分和右半部分,再递归排序,最后合并,代码如下:

void Msort(int a[],int tmp[],int left,int right)
{
	int center;//中间的位置
	if(left<right)
	{
		center=(left+right)/2;
		Msort(a,tmp,left,center);//先排前半部分
		Msort(a,tmp,center+1,right);//再排后半部分
		Merge(a,tmp,left,center+1,right);//前后两部分合并
	}
}

       最后就是归并排序的实现了,我们在该函数里定义了一个临时数组。

void MergeSort(int a[],int n)
{
	int *tmp;
	tmp=(int*)malloc(sizeof(int)*n);
	Msort(a,tmp,0,n-1);//调用归并排序的递归例程
}
       虽然归并排序的运行时间是O(N*logN),但是它很难应用于主存排序,主要问题在于合并两个排序的表需要线性附加内存,在整个算法中还要花费将数据拷贝到临时数组再拷贝回来这样一个附加工作,其结果就放慢了排序的速度。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值