数据结构与算法应用(八):分治算法

    当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
    利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。

这里写图片描述

/*
1.设计程序利用分治策略求n个数的最大值和最小值。
*/
void maxmin2(int A[],int i,int j,int *max,int *min)//分治
{ /*A存放输入的数据,i,j存放数据的范围,初值为0,n-1,*max,int *min 存放最大和最小值*/
	int mid,max1,max2,min1,min2;
	if (j==i) 
	{	
		*max=*min=A[i];		//	最大和最小值为同一个数;
		return;
	}
	if (j-1==i) 
	{
		*max=A[j]>A[i]?A[j]:A[i];	//	将两个数直接比较,求得最大值、最小值;
		*min=A[j]<A[i]?A[j]:A[i];
		return;
	}
	mid=(i+j)/2;
	maxmin2(A,i,mid,&max1,&min1);	//求i~mid之间的最大最小值分别为max1,min1;
	maxmin2(A,mid+1,j, &max2,&min2 );	//求mid+1~j之间的最大最小值分别为max2,min2;
	*max=max1>max2?max1:max2;		//	比较max1和max2,大的就是最大值;
	*min=min1<min2?min1:min2;		//	比较min1和min2,小的就是最小值;
}
void main()
{
	maxmin2(A,0,n-1,&max,&min);
	printf("the max number is : %d\n",max);		//输出结果
	printf("the min number is : %d\n",min);
}
/*
2.利用分治策略,在n个不同元素中找出第k个最小元素。
*/
void find(int A[],int k,int n,int *min)//利用分治策略,在n个不同元素中找出第k个最小元素
{ 	

	m=A[k];//取第k个元素作为标准m
	j=n/2;
	B[j]=m;
	for (x=1;x<=n;x++)//把n个元素重新排列
	{
		if (A[x]<m)//小于标准m的元素区间1~j
		{
			for (y=1;y<j;y++)
			{
				B[y]=A[x];
			}
		} 
		else//大于标准m的元素区间j+1~n
		{
			for (y=j+1;y<=n;y++)
			{
				B[y]=A[x];
			}
		}
	}
	if (j==k)//1)j=k,则找到第k个元素。
	{
		*min=m;
		return;
	}
	if (j<k)//2)j<k,则第k个元素在区间j+1~n。
	{
		find(B,k,j+1,n,&min);//在情况2继续寻找。
	} 
	else//3)j>k,则第k个元素在区间1~j。
	{
		find(B,k,1,j,&min);//在情况3继续寻找。
	}
}

void main()
{
	find(A,k,n,&min);//利用分治策略开始查找
	printf("the NO.%d min number is : %d\n",k,min);//输出结果值
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值