寻找最大子数组递归_C++实现

求解数组中的最大子数组问题:分治递归
	思想:
		把数组分为左右两部分,下标为:left,mid,right,最终的最大子数组的存在形式无非有三种:
			*存在于left-mid之间;
			*存在于mid两边;
			*存在于mid-right之间;
	递归问题特征:
		*问题解所在的域情况可数;
		*同级子问题之间相互独立;
		*同级子问题结果作为上一级问题参数;
		*问题边界有确定解;
		*子问题必须有返回值;
分治算法时间代价分析:
	T(n) = 2T(n/2)+Θ(n)
	T(n) = Θ(nlgn)

代码:

#include <iostream>
using namespace std;
int* findMaxSubArray_mid(int* arr, int left, int mid, int right);  //处理中间体,即递归结构主体
int* findMaxSubArray(int* arr, int left, int right); //寻找最大子数组函数

int main()
{
	//例子来源:算法导论(第三版)
	int arr[16]={13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
	//输出最大子数组索引值首位,以及最大子数组和
	cout<< findMaxSubArray(arr, 0, 15)[0] <<" "
		<< findMaxSubArray(arr, 0, 15)[1] <<" "
		<< findMaxSubArray(arr, 0, 15)[2] <<endl;
	return 0;
}

int* findMaxSubArray_mid(int *arr, int left, int mid, int right) {
	int* subArr = new int[3];
	int left_sum = -0x3f3f3f3f;  //初始化左右最大之和
	int right_sum = -0x3f3f3f3f;
	int sum = 0;
	int max_left;
	int max_right;
	for (int i = mid;i >= left;i--) {
		sum = sum + arr[i];
		if (sum > left_sum)
		{
			left_sum = sum;
			max_left = i;
		}
	}
	sum = 0;
	for (int j = mid+1;j <= right;j++) {
		sum = sum + arr[j];
		if (sum > right_sum) {
			right_sum = sum;
			max_right = j;
		}
	}
	subArr[0] = max_left;
	subArr[1] = max_right;
	subArr[2] = left_sum + right_sum;
	return subArr;
}

int* findMaxSubArray(int *arr, int left, int right) {
	//开辟数组存放左边、右边、中间找到的最大子数组信息,用于比较
	int* subArrLeft = new int[3];
	int* subArrRight = new int[3];
	int* cossingMidSum = new int[3];
	int mid;
	if (left == right) {
		subArrLeft[0] = left;
		subArrLeft[1] = right;
		subArrLeft[2] = arr[left];
		return subArrLeft;
	}
	else {
		mid = (left + right) / 2;
		subArrLeft = findMaxSubArray(arr, left, mid);
		subArrRight = findMaxSubArray(arr, mid+1, right);
		cossingMidSum = findMaxSubArray_mid(arr, left, mid, right);
		if (subArrLeft[3] >= subArrRight[3] && subArrLeft[2] >= cossingMidSum[2])
			return subArrLeft;
		else if (subArrRight[2] >= subArrLeft[2] && subArrRight[2] >= cossingMidSum[2])
			return subArrRight;
		else
			return cossingMidSum;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值