《算法导论》——分治法求解最大子数组

《算法导论》——分治法求解最大子数组

最大字数组问题即对某一数组A,其元素有正有负,找到一个子数组,其元素是连续的且其和最大。在这里插入图片描述

#include "iostream"
using namespace std;

struct uin      //创建返回值数据结构
{
	int low;     //最大子数组的左起点
	int high;    //终点
	int sum;	//值
};
uin Find_crossmax(int*a, int left, int right, int mid)//若最大子数组包含中点
{
	uin res;
	int leftsum = INT32_MIN;
	int rightsum = INT32_MIN;
	int sum = 0;
	for (int i = mid; i >= left; i--)
	{
		sum += a[i];
		if (sum > leftsum)
		{
			leftsum = sum;     //左侧连续的最大值
			res.low = i;
		}
	}
	sum = 0;
	for (int i = mid + 1; i <= right; i++)
	{
		sum += a[i];
		if (sum > rightsum)
		{
			rightsum = sum; // 右侧连续的最大值
			res.high = i;
		}
	}
	res.sum = leftsum + rightsum;
	return res;
}
uin Find_maxsubarry(int* a, int left, int right, int mid)
{
	uin result;
	if (left == right)         //递归到最后时返回
	{
		result.low = left;
		result.high = right;
		result.sum = a[left];
		return result;
	}
	uin lsum = Find_maxsubarry(a, left, mid, (left + mid) / 2);
	uin rsum = Find_maxsubarry(a, mid + 1, right, (mid + 1 + right) / 2);
	uin crosssum = Find_crossmax(a, left, right, mid);
	if (lsum.sum >= rsum.sum && lsum.sum >= crosssum.sum)
		return lsum;
	else if (rsum.sum >= lsum.sum && rsum.sum >= crosssum.sum)
		return rsum;
	else if (crosssum.sum >= rsum.sum && crosssum.sum >= lsum.sum)
		return crosssum;

}

void main()
{
	int a[] = { 8, -1, -5, 4, 9, -8, 0, 1 };
	int len = sizeof(a) / sizeof(a[0]);
	uin ptr = Find_maxsubarry(a, 0, len - 1, (0 + len - 1) / 2);
	cout << "最大子数组的左起始为" << ptr.low << " " << "右起始为" << ptr.high << " " << "最大值为:" << ptr.sum << endl;
	system("pause");
}

猜你喜欢

转载自blog.csdn.net/weixin_42809993/article/details/84759408