分治算法就是将一个问题分解成若干个小问题,对若干个小问题分别求解,最后在合并起来
最大子段问题课以分成三种情况
1.数组a[1-n](即数组前1至n个元素) 的最大子段和a[1-n/2]的最大子段相同
2数组a[1-n](即数组前1至n个元素) 的最大子段和a[n/2+1-n]的最大子段相同
3.数组a[1-n]的最大子段和是由a[1-n/2]和a[n/2+1-n]结合而成,求解方法为
则分别求出
n/2 i
max ∑a[k] 和 max ∑a[k] ,然后将两个值相加即得到此种情况下的数组最大子段和
0<=i<=n/2 k=i n/2+1<=i<=n k=n/2
最后分别求出三种情况的最大子段和,再比较三个子段和,最大的那个即为数组的最大字段和
源代码:
// 最大子段 分治算法.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
/*****************************************************88
定义了一个存储结果的结构体
*******************************************************888*/
struct result
{
int max;//存储最大字段值
int startindex;//存储最大字段开始下标
int endindex;//存储最大字段结束下标
};
/********************************************************
函数名: Phalf
参数类型:int a[] , int n1 , int n2
返回值:struct result
功能:求在数组的n1至n2间的最大字段
***********************************************************/
struct result Phalf(int a[] , int n1 , int n2)
{
struct result half;
int flags = 0;
//int max = 0;
for(int i=n1;i<n2;i++)
{
int sum = a[i];
if(flags==0)
{
half.max = sum;
flags = 1;
}
if(sum>half.max)
{
half.max = sum;
half.startindex = i;
half.endindex = i;
}
for(int j=i+1;j<n2;j++)
{
sum += a[j];
if(sum>half.max)
{
half.max = sum;
half.startindex = i;
half.endindex = j;
}
}
}
return half;
}
/**********************************************
函数名:summax
参数类型:int a[] , int n
返回值:struct result
功能:当数组a的最大子段既不在前半段中也不在后半段中
则分别求出n/2 i
max ∑a[k] 和 max ∑a[k] ,然后将两个值相加
0<=i<=n/2 k=i n/2+1<=i<=n k=n/2
***********************************************/
struct result summax(int a[] , int n)
{
int Fhalfmax;
int Shalfmax;
int Fsum;
int Ssum;
int flags = 0;
struct result half;
half.startindex = 0;
half.endindex = (n+1)/2;
for(int i=0;i<(n+1)/2-1;i++)
{
Fsum = a[i];
if(flags==0)
{
Fhalfmax = Fsum;
flags =1 ;
}
for(int j=i+1;j<(n+1)/2;j++)
{
Fsum += a[j];
}
if(Fhalfmax<Fsum)
{
Fhalfmax = Fsum;
half.startindex = i;
}
}
if(Fhalfmax<a[(n+1)/2-1])
{
Fhalfmax = a[(n+1)/2-1];
half.startindex = (n+1)/2-1;
}
Ssum = a[(n+1)/2];
if(flags==1)
{
Shalfmax = Ssum;
flags =0 ;
}
for(int j1=(n+1)/2+1;j1<n;j1++)
{
Ssum += a[j1];
if(Shalfmax<Ssum)
{
Shalfmax = Ssum;
half.endindex = j1;
}
}
if(Shalfmax<a[n-1])
{
Shalfmax = a[n-1];
half.endindex = n-1;
}
half.max = Shalfmax+Fhalfmax;
return half;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[10];
int flags = 1;
for(int i=0;i<10;i++)
scanf("%d" , &a[i]);
struct result half[3];
half[0] = Phalf(a , 0 , 5);
half[1] = Phalf(a , 5 , 10);
half[2] = summax(a , 10);
int max = half[0].max;;
int index = 0;
for(int i=1;i<3;i++)
{
if(half[i].max>max)
{
max = half[i].max;
index = i;
}
}
printf("max = %d , startindex = %d , endindex = %d\n" , half[index].max , half[index].startindex , half[index].endindex);
return 0;
}
运行结果:
第一种情况:
第二种情况:
第三种情况: