归并排序算法

归并算法实质是由两部分算法形成的:

        第一部分是通过分治思想,通过把同一类的元素简化为n个子序列,每个子序列的长度为1

         第二部分是通过两个子序列通过比大小的方式归并为一个子序列

我们可以先来看看两个数组如何归并为一个有顺序的数组

#include <stdio.h>
int main()
{
	int i,j,L,p;
	int max[10];
	int num[5]={2,4,6,8,9};
	int ber[5]={3,4,5,7,8};
	
	for(i=0,j=0,p=0;i<=4&&j<=4;p++)
	{
		if(num[j]>ber[i])
			max[p]=ber[i++];
		else
			max[p]=num[j++];
	}
	
	if(i<=4)
	{			
		for(L=0;L<=4-i;L++)
		max[p+L]=ber[i+L];
	}else
	{
		for(L=0;L<=4-j;L++)
		max[p+L]=num[j+L];
	}
	
	for(i=0;i<10;i++)
	{
		printf("%d\n",max[i]);
	}
	
	return 0;
}

 

如上图所示便是两个数组比大小然后归并的过程,请注意以下几点:

(1)是两个数组的范围问题:也就是说如果其中一个数组内的元素全部排完则两数组比较结束,如上所示范围是i<=4

(2)是剩余元素加入的范围问题,设置了个变量L,从而使得剩余元素例如从num[i]到num[5]加入到max中

(3)是采用此方法的前提必须是两个数组都是已排序(遵从从小到大的顺序)的状态!!!!

分治思想的运用一般采用递归的方式进行

/*r[]代表原来本身的数组,s[]用于储存排序完成的数组,*/
/*left代表左值,right代表右值*/
int merge_sort(int r[],int s[],int left,int right)   
{
    int mid;
    int t[20];  /*t[20]作为一个临时储存数组,用于储存子序列的元素*/
    if(left==right) /*此处为递归结束条件*/
        s[left]=r[right];
    else
    {
        mid=(left+right)/2;
        merge_sort(r,t,left,mid);
        merge_sort(r,t,mid+1,right);
        merge(t,s,left,mid,right);/*将t(left,mid)与t(mid+1,right)归并为s[]*/
    }
    return 0;
}

递归的进行离不开对递归结束的判断以及分治的运行:

(1)通过if……else来判断递归的结束

(2)其次是merge_sort的本身:

       r[ ]数组是原数组,即被操作数组,通过被mid不断的划分,直至变为长度为1的子序列(上图if语句处,然后赋值给t[ ](临时数组),

(3)由于递归函数本身的顺序,merge函数运行时,开始逐步归并(从子序列为1,反向进行上述分治操作)     这保证了比较的数组都符合从小到大的顺序,进行第一部分操作

下面是一个数组的分治对比,可以类比上面两个数组的对比

void merge(int SR[],int TR[],int i,int m,int,n)
{
	int j,k,l;
	for(j=m+1,k=i;j<n&&i<m;k++)
	{
		if(SR[i]<SR[j])
	{
			TR[k]=SR[i++];
		else
			TR[k]=SR[j++];
	}
	if(i<=m)
	{
		for(l=0;l<=m-i;l++)
		{
			TR[k+l]=SR[j+l];
		}
	}else
	{
		for(l=0;l<=n-j;l++)
		{
			TR[k+l]=SR[j+l];
		}
	}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值