归并算法进行排序

        归并算法是一种效率较高且稳定的算法,归并算法总是要将序列中的记录都扫描一遍,所以总的时间复杂度为o(nlogn),这是归并算法中最好、最坏、平均的时间性能。

       递归方式的归并算法:

       首先定义函数 sort(int SR[ ], int s, int t),

void sort(int SR[], int s, int t)
{
	int temp;
	if(SR[s] > SR[t])
	{
		temp = SR[t];
		SR[t] = SR[s];
		SR[s] = temp;
	}
	return;
}

        sort函数的作用是将数组SR[]中下标为s和t的两个元素的位置进行交换。

        接下来是比较关键的Merge函数,Merge(int SR[ ], int s, int m, int t)

void Merge(int SR[], int s, int m, int t)
{
	int temp[MAXSIZE];
	int k;
	int i, j;
	k = 0;
	i = s;
	j = m+1;
	while(i<=m&&j<=t)
	{
		if(SR[i] < SR[j])
		{
			temp[k] = SR[i];
			++k;
			++i;
		}
		else
		{
			temp[k] = SR[j];
			++k;
			++j;
		}
	}
	if(i>m)
	{
		while(j<=t)
		{
			temp[k] = SR[j];
			++k;
			++j;
		}
	}
	else
	{
		while(i<=m)
		{
			temp[k] = SR[i];
			++k;
			++i;
		}
	}
	for(j = s; j<=t;++j)
		SR[j] = temp[j-s];
	
}
这个函数的作用是这样的,假设SR[s.........m]数组已经是有序数组,SR[m+1..............t]数组也是有序数组,要将他们归并成一个有序数组SR[s..........................t]。

最后的总函数void MSort(int SR[ ], int s, int t)

void MSort(int SR[], int s, int t)
{
	if(s==t)
		return;
	if((s+1)==t)
	{
		sort(SR,s,t);
		return;
	}
	else
	{
		int m;
		m = (s+t)/2;
		MSort(SR, s, m);
		MSort(SR, m+1, t);
		Merge(SR,s, m, t);
	}
}

        分析下其空间复杂度,Merge函数中需要另外分配空间temp[MAX],加上递归造成的函数的堆栈深度log(n),所以总的空间复杂度是o(log(n) +n)(大话数据结构)。

        采用递归的方法进行递归调用的时候,需要重新开辟栈空间,又要返回,会造成时间和空间上的损耗,下面是非递归调用所采用的代码。

首先是函数MergePass(int array, int s, int n)

void MergePass(int array[], int s, int n)
{
	if(n<=s)
		return;
	if(s<n&&n<=2*s)
		Merge(array,1, s, n);
	else
	{
		int i;
		i = 1;
		while((i+2*s-1)<=n)
		{
			Merge(array, i, i+s-1, i+2*s-1);
			i = i+2*s;
		}
		if((i+s-1)>=n)
			return;
		else
		{
			Merge(array, i, i+s-1, n);
		}
	}
}
         这个函数的作用是这样的,从第一个元素开始,将array中相邻的长度为(元素个数)s的子序列两两归并,array序列具有这样的性质,从第一个元素开始,每个长度为s的序列都是有序的,划分到最后,如果序列长度小于或等于s,这个序列也是有序的,这个函数的作用就是将array序列每s个元素有序变成每2s个元素有序,注意其中序列的几种情况的不同处理。

最后的函数是这样的:

void FinalMerge(int array[], int n)
{
	int k;
	for(k =1; k<=n;k = k*2)
		MergePass(array, k, n);
}

k从1开始两两归并,然后k等于2,再来两两归并,然后k等于4来进行两两归并.....最后整个数列成为有序数列。

此外要特别注意的是各个参数和数组中元素的对应关系(C语言中数组中第一个元素的下标为0)。

非递归的方法不需要消耗因递归调用引起的时间和空间,空间复杂读o(n)(Merge函数中需要的空间),时间复杂度是归并排序的时间复杂度o(nlogn)。

主要参考《大话数据结构》,代码以及函数参数稍有变化,以上代码已经进行测试。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值