/************************************************************************* File Name: maxSubSequence.c Author: *** Mail: *******@**.com Created Time: 2015年07月18日 19:38:14 Description:求最大子序列的四种算法,数据结构与算法分析(C语言版)第二章 ************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<time.h> 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<n;i++) { /* 找出A[i...n-1]序列(是A[0...n-1]的子序列)中以i为起点的最大子序列,并找出终点 */ for(j=i;j<n;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<n;i++) { sum=0; /* 找出A[i...n-1]序列(是A[0...n-1]的子序列)中以i为起点的最大子序列,并找出终点 */ for(j=i;j<n;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<n;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; }