1. 程式人生 > >《演算法導論》——分治法求解最大子陣列

《演算法導論》——分治法求解最大子陣列

《演算法導論》——分治法求解最大子陣列

最大字陣列問題即對某一陣列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");
}