/*************************************************************************
File Name: maxSubSequence.c
Author: ***
Mail: *******@**.com
Created Time: 2015年07月18日 19:38:14
Description:求最大子序列的四种算法,数据结构与算法分析(C语言版)第二章
************************************************************************/
#include
#include
#include
int MaxSubSequenceSum1(int A[],int n,int *start,int *end)
{
int sum,maxSum,i,j,k;
maxSum=A[0];
*start=*end=1;
/* 找出A[0...n-1]序列中的最大子序列,通过不断的遍历所有可能的起点,去寻找终点 */
for(i=0;imaxSum)
{
maxSum=sum;
*start=i+1;
//最内层循环已经结束;k==j+1;
*end=k;
}
}
}
return maxSum;
}
int MaxSubSequenceSum2(const int A[],const int n,int *start,int *end)
{
/* 这个算法和算法1原理一样,只是算法1在内循环中进行了不必要的计算 */
int sum,maxSum,i,j;
maxSum=A[0];
*start=*end=1;
/* 找出A[0...n-1]序列中的最大子序列,通过不断的遍历所有可能的起点,去寻找终点 */
for(i=0;imaxSum)
{
maxSum=sum;
*start=i+1;
*end=j+1;
}
}
}
return maxSum;
}
/* 分治算法 */
int MaxSubSequenceSum3(int A[],int left,int right,int *start,int *end)
{
int MaxL,MaxR,ls,le,rs,re,MaxM,ms,me,MidLeft,MidLeftMax,
MidRight,MidRightMax,Mid,i;
//基本情况
if(left==right)
{
*start=*end=left;
return A[left-1];
}
//计算中间点
Mid=(left+right)/2;
//计算左边部分最大子序列
MaxL=MaxSubSequenceSum3(A,left,Mid,&ls,&le);
//计算右边部分最大子序列
MaxR=MaxSubSequenceSum3(A,Mid+1,right,&rs,&re);
//计算中间部分最大子序列
MidLeft=0;
MidLeftMax=A[Mid-1];
ms=Mid;
for(i=Mid;i>=left;i--)
{
MidLeft+=A[i-1];
if(MidLeft>MidLeftMax)
{
MidLeftMax=MidLeft;
ms=i;
}
}
MidRight=0;
MidRightMax=A[Mid];
me=Mid+1;
for(i=Mid+1;i<=right;i++)
{
MidRight+=A[i-1];
if(MidRight>MidRightMax)
{
MidRightMax=MidRight;
me=i;
}
}
MaxM=MidLeftMax+MidRightMax;
//获得最大子序列
if(MaxL>MaxR&&MaxL>MaxM)
{
*start=ls;
*end=le;
return MaxL;
}
else if(MaxR>MaxL&&MaxR>MaxM)
{
*start=rs;
*end=re;
return MaxR;
}
else
{
*start=ms;
*end=me;
return MaxM;
}
}
int MaxSubSequenceSum4(int A[],int n,int *start,int *end)
{
int sum,maxSum,i;
sum=0;
maxSum=A[0];
*start=*end=1;
for(i=0;imaxSum)
{
maxSum=sum;
*end=i+1;
}
//sum小于0,表示最大子序列不可能包括这部分序列
else if(sum<0)
{
sum=0;
*start=*end=i+2;
}
}
return maxSum;
}
int main()
{
int A[16]={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7},start,end;
printf("%d\n",MaxSubSequenceSum1(A,16,&start,&end));
printf("%d %d\n",start,end);
printf("%d\n",MaxSubSequenceSum2(A,16,&start,&end));
printf("%d %d\n",start,end);
printf("%d\n",MaxSubSequenceSum3(A,1,16,&start,&end));
printf("%d %d\n",start,end);
printf("%d\n",MaxSubSequenceSum4(A,16,&start,&end));
printf("%d %d\n",start,end);
return 0;
}