分治策略之最大子数组问题

/****************************************************************
用分治法解决最大子数组和问题:
最大子数组的位置有以下三种情况:
1:最大子数组位于左半部分A[low,mid]中;
2:最大子数组位于右半部分A[mid+1,high]中;
3:最大子数组跨越了中点,同时位于左半部分和右半部份;

对于第三种情况,最大子数组的和等于从中点开始向左半部分的
最大和加上从中点开始向右半部份的最大和
输入:
	第一行为数组元素个数,第二行为数组中的元素值,如下:
	16
	13 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7
输出:
	43
****************************************************************/
#include <stdio.h>
#include <stdlib.h>
//子方法,求跨越中点的最大子数组和,这也相当于分治法中的合并过程
int FIND_MAX_CROSSING_SUBARRAY(int *A,int low,int mid,int high)
{
	//从中点向左找出左半部分的最大子数组和
	int left_max=-65536;
	int sum=0;
	for(int i=mid;i>=low;i--)
	{
		sum=A[i]+sum;
		if(sum>left_max)
			left_max=sum;
	}
	
	//从中点向右找出右半部分的最大子数组和
	int right_max=-65536;
	sum=0;
	for(int i=mid+1;i<=high;i++)
	{
		sum=A[i]+sum;
		if(sum>right_max)
			right_max=sum;
	}
	return left_max+right_max;
}

//主方法,求最大子数组和
int FIND_MAXIMUM_SUBARRAY(int *A,int low,int high)
{
	//递归的基本情况
	if(low==high)
		return A[low];
	//递归情况
	else
	{
		int mid=(low+high)/2;
		int left_max=FIND_MAXIMUM_SUBARRAY(A,low,mid);
		int right_max=FIND_MAXIMUM_SUBARRAY(A,mid+1,high);
		int mid_max=FIND_MAX_CROSSING_SUBARRAY(A,low,mid,high);
		if(left_max>=right_max&&left_max>=mid_max)
			return left_max;
		else if(right_max>=left_max&&right_max>=mid_max)
			return right_max;
		else if(mid_max>=right_max&&mid_max>=left_max)
			return mid_max;
	}
}
int main()
{
	int length;
	int *A;
	int max,sum,maxi,maxj;
	while(scanf("%d",&length)==1)
	{
		if(length!=0)
		{
			//输入数组元素
			A=(int *)malloc(sizeof(int)*length);
			for(int i=0;i<length;i++)
			{
				scanf("%d",&A[i]);
			}
			
			printf("max_sub_sum:%d\n",FIND_MAXIMUM_SUBARRAY(A,0,length-1));
		}
		else break;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦时小

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值