归并排序(递归与非递归)

1.递归:

把序列分成元素个数尽量相等的两部分,再将两半分别排序,合并有序的两个序列


//递归 
void merge_sort(int *A, int low, int heigh, int *T) 
//A为待排序数组,low,high分别为A的上下限(0~n-1),T为辅助数组 
{
	int i,j,k,mid;    

	if(heigh-low > 0)
	{
		mid = low + (heigh-low)/2;
		merge_sort(A, low, mid, T);
		merge_sort(A, mid+1, heigh, T); //递归 
		
		i=low; j=mid+1; k=0;
		while(i<=mid || j<=heigh)
		{
			if(j>heigh || (i<=mid && A[i]<=A[j]))  //包含左右数组非空和左非空右空 
				T[k++] = A[i++];		//左边的复制到辅助数组 T; 
			else
				T[k++] = A[j++];		//右边的复制到辅助数组 T;
		}
		
		for(i=low, j=0; i<=heigh; i++, j++)
		{
			A[i] = T[j];				//将T中排好序的复制回A; 
		}
	}
}


2.非递归:

首先查找数组中自然排序好的序列,两两合并,循环下去,直到不再合并即为有序

void merge(int *A, int l, int m, int r) //合并函数 
{
	int i=l, j=m+1;  //l,m,r分别为两个序列的上下序号,m为分界处,即m为第一个序列的下界,m+1为第二个的上界 
	int p=0, q;
	int *T;
	T=(int *)malloc((r-l+1)*sizeof(int)); //辅助数组 
	
	if(!T) return;
	
	while(i<=m && j<=r)       //分情况合并,与上面递归中效果相同(递归中用了短路或,写起来方便点)  
	{							//左右非空 
		if(A[i]<=A[j])
			T[p++] = A[i++];
		else
			T[p++] = A[j++];
	}
	
	if(i>m)						//左空右非空 
	{
		for(q=j; q<=r; q++)
		{
			T[p++] = A[q];
		}
	}
	else						//左非空右空 
	{
		for(q=i; q<=m; q++)
		{
			T[p++] = A[q];
		}
	}
	
	for(p=l, q=0; p<=r; p++, q++)	//将T中排好序的复制回A中 
	{
		A[p]=T[q];
	}
} 

void fun(int *A, int n)	//排序,A为待排序数组,n为数组中元素个数 
{
	int i;
	int low, mid, heigh; //low,mid,heigh记录两个合并的序列指针 
	int flag;			//判断是否有序 
	while(1)
	{	flag=1;i=0;
		while(i<n-1)
		{
			low = i;
			while(i<n-1 && A[i]<=A[i+1])
			{
				i++;
			}
			mid = i++;
			
			while(i<n-1 && A[i]<=A[i+1])
			{
				i++;
			}
			heigh = i++;
			
			if(i<=n)
			{
				merge(A, low, mid, heigh);
				flag++;  //flag不变则已有序 
			}
		}
		if(flag==1) break;
	
	}
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值