最大子列和实现算法(三种方式)-----C语言

首先给出一个main函数,可以直接替换函数即可,我默认写的是五位数,需要多少可以自行替换

#include<stdio.h>
#define N 5
int MaxSubSeq(int list[]);
int main(){
	int list[N];
	printf("Input list:\n");
	for(int i = 0;i<N;i++){
		scanf("%d",&list[i]);
	}
	int maxSubSum = MaxSubSeq(list);
	printf("maxSubSum:%d\n",maxSubSum);
	return 0;
} 

1.遍历:三重循 直接一个一个遍历

int MaxSubSeq(int list[]){
	// 循环的变量 
	int i,j,k;
	// 暂时的最大和,最大子列和 
	int tempSum,MaxSubSum = 0;
	for(i = 0;i<N;i++){
		for(j = i;j<N;j++){
			// 每一轮将暂时的最大和置为0 
			tempSum = 0;
			// 求和
			for(k = i;k<=j;k++){
				tempSum = tempSum+list[k];
			}
			// 与最大子列和进行比较,如果比MaxSubSum大就给替换掉
			if(tempSum>MaxSubSum){
				MaxSubSum = tempSum;
			} 
		}
	}
	return MaxSubSum;
}

2.第三重循环 计算2个数和的时候,又重新计算了1个数的和,其实根本第三次循环没必要,进行优化累加求和

int MaxSubSeq(int list[]){
	// 循环的变量 
	int i,j,k;
	// 暂时的最大和,最大子列和 
	int tempSum,MaxSubSum = 0;
	for(i = 0;i<N;i++){
		// tempSum每新一轮重新置为0 
		tempSum = 0; 
		for(j = i;j<N;j++){
			// 累加求和 
			tempSum = tempSum+list[j];
			// 与最大子列和进行比较
			if(tempSum>MaxSubSum){
				MaxSubSum = tempSum;
			} 
		}
	}
	return MaxSubSum;
}

3.分而治之 递归实现 以五个数为例 进行一下详细的计算过程
首先用递归,我们要知道,递归终止的条件,当把所有元素分成独立的一个元素的时候就是递归结束的条件,求出左右的子列和,不妨假设左边为S1,右边为S2,从左边起到右边结束为S3,比较这三个,三个中最大的就是最大子列和。

#include<stdio.h>
#define N 5
int SubSeq(int list[],int left,int right);
int SumSubSeq(int list[],int left,int mid,int right);
int MaxSubSeq(int s1,int s2,int s3);
int main(){
	int list[N];
	printf("Input list:\n");
	for(int i = 0;i<N;i++){
		scanf("%d",&list[i]);
	}
	int maxSubSum = SubSeq(list,0,4);
	printf("maxSubSum:%d\n",maxSubSum);
	return 0;
} 

int SubSeq(int list[],int left,int right){
	int s1,s2,s3;
	// 递归终止条件 直到分到最后一个元素 
	if(left==right){
		return list[left];  
	}
	int mid = (left+right)/2;
	// 划分左边
	s1 = SubSeq(list,left,mid);
	// 划分右边
	s2 = SubSeq(list,mid+1,right);
	// 求解s3 
	s3 = SumSubSeq(list,left,mid,right);
	return MaxSubSeq(s1,s2,s3);
}
// 求解s3 
int SumSubSeq(int list[],int left,int mid,int right){
	int leftSum = 0;
	int rightSum = 0;
	int sum = 0;
	for(int i = mid;i>=left;i--){
		sum = sum+list[i];
		if(sum>leftSum){
			leftSum = sum;
		}
	}
	sum = 0;
	for(int j = mid+1;j<=right;j++){
		sum = sum+list[j];
		if(sum>rightSum){
			rightSum= sum;
		}
	}
	
	return leftSum+rightSum;
}

// 求解最大的子列和 
int MaxSubSeq(int s1,int s2,int s3){
	int maxSum = s1>s2?s1:s2;
	return maxSum>s3?maxSum:s3;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值