归并排序的递归和非递归方法总结

归并排序的主要思想是,初始:假设两个子数组都有序,那么就可以通过比较用另外一个数组来存储比较后的有序数组。扩散:于是我们可以把一个数组看成是n个长度为1的有序子数组,通过合并成n/2上界个长度为2的子数组,然后再把n/2个子数组,两两合并成n/4个长度为4的有序子数组.....最后合并成一个有序的长度为n的数组,

递归方法:左边进行递归的有序子序列合并,右边进行有序子序列合并,然后对当前的已经完成有序合并的左右两部分进行合并。

(记住:在递归中后调用的先返回,先调用的后返回)

非递归方法:用len标注进行合并的子数组的长度,初始长度为1,然后两两合并,最后可能会剩下不足2*len的子数组,当不足len的,直接复制过去,>len得,再进行一次到数组末尾的合并。

// SortAlri.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
/*
对两方都有序的数组进行合并,

*/
template<class type> void Merge(type * a,type * b,int left,int  mid,int right){
	int i=left,j=mid+1;
	int k=left;
	while(i<=mid&&j<=right){
		if(a[i]<=a[j]){
		  b[k]=a[i];
		  i++;k++;
		}else {
		b[k]=a[j];
		j++;k++;
		}
	}
	if(i<=mid){
	   for( ;i<=mid;i++,k++)
		b[k]=a[i];
	}else{
	
		for(;j<=right;j++,k++)
			b[k]=a[j];
	}

}

template<class type> void None_MergeSort(type * a,type *b,int lenth){
	//进行合并的长度,刚开始为1进行两两合并,然后进行长度为2两两合并,直到剩下只有两个有序数组进行合并
	int len=1;
	while(len<lenth){
		WholeMerge(a,b,lenth,len);	
		len+=len;
		WholeMerge(b,a,lenth,len);
		len+=len;
	}
}

template<class type> void  WholeMerge(type * sourceTable,type * mergedTable,int lenth,int len){//lenth:整个数组的长度-1(,len:进行合并的子数组长度
	int i=0;
	while(i<=lenth-2*len){
		Merge(sourceTable,mergedTable,i,i+len-1,i+2*len-1);
		i+=2*len;
	}
	if(i+len<lenth){
		
		Merge(sourceTable,mergedTable,i,i+len-1,lenth-1);
	}
	else{
		for(;i<lenth;i++)
			mergedTable[i]=sourceTable[i];
	}
}

template<class type> void MergeSort(type * a,type * b,int left,int right){
	
	if(left<right){
		int mid=(left+right)/2;
		MergeSort(a,b,left,mid);
		MergeSort(a,b,mid+1,right);
		Merge(a,b,left,mid,right);//把数据合并到b
		for(int j=left;j<=right;j++)//复制回a
			a[j]=b[j];
	
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	int a[11]={6,23,46,31,83,65,77,6,38,19,56};
	int b[11];
	None_MergeSort<int>(a,b,11);
	//MergeSort<int>(a,b,0,10);
	for(int i=0;i<=10;i++)
		cout<<a[i]<<"   ";
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值