子序列的判定算法c语言,求最大子序列的四种算法,数据结构与算法分析(C语言版)第二章...

/*************************************************************************

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;i

{

/* 找出A[i...n-1]序列(是A[0...n-1]的子序列)中以i为起点的最大子序列,并找出终点 */

for(j=i;j

{

sum=0;

for(k=i;k<=j;k++)

sum+=A[k];

if(sum>maxSum)

{

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;i

{

sum=0;

/* 找出A[i...n-1]序列(是A[0...n-1]的子序列)中以i为起点的最大子序列,并找出终点 */

for(j=i;j

{

sum+=A[j];

if(sum>maxSum)

{

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;i

{

sum+=A[i];

if(sum>maxSum)

{

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值