#include <stdio.h>
//返回包括中间元素在内的子序列最大和,通过指针带回该子序列首尾位置
int maxCrossingSub(int a[],int *low,int *high,int mid)
{
int tLow=(*low),tHigh=(*high);
int rightMax=-9999,leftMax=-9999,sum=0;
int i,j;
for(i=mid;i>=tLow;i--)
{
sum+=a[i];
if(sum>leftMax)
{
leftMax=sum;
(*low)=i;
}
}
sum=0;
for(j=mid+1;j<=tHigh;j++)
{
sum+=a[j];
if(sum>rightMax)
{
rightMax=sum;
(*high)=j;
}
}
return leftMax+rightMax;
}
//返回子序列最大和,通过指针带回该子序列首尾位置
int maxSub(int a[],int* low,int* high)
{
int tLow=(*low),tHigh=(*high);
//基本情况
if(tLow==tHigh)
{
return a[tLow];
}
int mid=(tLow+tHigh)/2;
int leftLow=tLow,leftHigh=mid,rightLow=mid+1,rightHigh=tHigh,midLow=tLow,midHigh=tHigh;
//左递归情况
int leftSum=maxSub(a,&leftLow,&leftHigh);
//右递归情况
int rightSum=maxSub(a,&rightLow,&rightHigh);
//合并
int midSum=maxCrossingSub(a,&midLow,&midHigh,mid);
if(leftSum>=rightSum && leftSum>=midSum)
{
(*low)=leftLow;
(*high)=rightHigh;
return leftSum;
}
if(rightSum>=leftSum && rightSum>=midSum)
{
(*low)=rightLow;
(*high)=rightHigh;
return rightSum;
}
if(midSum>=leftSum && midSum>=rightSum)
{
(*low)=midLow;
(*high)=midHigh;
return midSum;
}
}
int main()
{
int a[16]={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
int low=0;int high=15;
int max=maxSub(a,&low,&high);
printf("%d,%d,%d",low,high,max);
getchar();
}
算法导论 最大子数组问题(分治策略)
最新推荐文章于 2018-12-17 23:40:54 发布