标签:
/*
本问题是求解最大子数组问题
普通方法的复杂度为n^2
现在尝试给出一种小于n^2的算法
当然数组中必须要有负数,不然没有意义
本例中使用分治策略
*/
#include<stdio.h>
#include<stdlib.h>
//定义返回结构体
typedef struct result
{
int left; //左索引
int right; //右索引
int sum; //最大和
}*Res;
//求解包含中间值的最大子数组,复杂度为n
Res findMaxCrossingSubarray(int *A,int left,int mid,int right)
{
Res R=malloc(sizeof(struct result));
int leftSum=*(A+mid);
int sum=0;
int i;
int maxLeftIndex=mid;
for(i=mid;i>=left;i--) {
sum+=*(A+i);
if(sum>leftSum) {
leftSum=sum;
maxLeftIndex=i;
}
}
int rightSum=*(A+mid+1);
sum=0;
int j;
int maxRightIndex=mid+1;
for(j=mid+1;j<=right;j++) {
sum+=*(A+j);
if(sum>rightSum) {
rightSum=sum;
maxRightIndex=j;
}
}
R->left=maxLeftIndex;
R->right=maxRightIndex;
R->sum=(leftSum+rightSum);
return R;
}
//接下来采用分治法来找到一个数组的最大子数组序列,注意前提是有负数元素,不然无意义
Res findMaxSubarray(int *A,int low,int high)
{
if(high==low) {
Res res=malloc(sizeof(struct result));
res->left=low;
res->right=high;
res->sum=*(A+low);
return res;
}
else {
int mid=(low+high)/2;
Res resLeft=findMaxSubarray(A,low,mid);
Res resRight=findMaxSubarray(A,mid+1,high);
Res resCross=findMaxCrossingSubarray(A,low,mid,high);
if((resLeft->sum) >= (resRight->sum) && (resLeft->sum) >= (resCross->sum))
return resLeft;
else if((resRight->sum) >= (resLeft->sum) && (resRight->sum) >= (resCross->sum))
return resRight;
else
return resCross;
}
}
//主测试程序
void main()
{
int A[8]={5,-1,4,5,-2,3,-1,2};
Res res=findMaxSubarray(A,0,7);
printf("%d\n",res->sum);
}
标签:
原文地址:http://my.oschina.net/zzw922cn/blog/484420