算法导论_分治法_最大子数组C++实现
只是机械实现,和算法导论的伪代码区别不大;复杂度分析 T(n)=2T(n/2)+O(n),由主定理(算法导论内容),时间复杂度为O(nlgn).
#include<iostream>
using namespace std;
//寻找跨越中点的最大子数组;
void find_crossing_subarray(int*a, int low, int mid, int high, int& start, int& end, int& max_sum) {
int left_sum = INT32_MIN;
int sum = 0;
for (int i = mid; i >= low; i--) {
sum += a[i];
if (sum>left_sum) {
start = i;
left_sum = sum;
}
}
int right_sum = INT32_MIN;
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if (sum > right_sum) {
end = i;
right_sum = sum;
}
}
max_sum = left_sum + right_sum;
}
void find_maximum_subarray(int*a, int low, int high, int&start, int&end, int&max_sum) {
if (high == low) {
start = low;
end = high;
max_sum = a[high];
}
else {
int mid = (high + low) / 2;
//查找中点左侧的最大子数组;
int left_start, left_end, left_sum;
find_maximum_subarray(a, low, mid, left_start, left_end, left_sum);
//寻找中点右侧的最大子数组;
int right_start, right_end, right_sum;
find_maximum_subarray(a, mid + 1, high, right_start, right_end, right_sum);
int cross_start, cross_end, cross_sum;
//寻找跨越中点的最大子数组;
find_crossing_subarray(a, low, mid, high, cross_start, cross_end, cross_sum);
//将三种情况的最大值设为当前数组的最大子数组;
if ((left_sum >= cross_sum) && (left_sum >= right_sum)) {
start = left_start;
end = left_end;
max_sum = left_sum;
}
else if ((cross_sum >= left_sum) && (cross_sum >= right_sum)) {
start = cross_start;
end = cross_end;
max_sum = cross_sum;
}
else {
start = right_start;
end = right_end;
max_sum = right_sum;
}
}
}
int main() {
int n;
cin >> n;
int a[1000];
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
int max=0,start = 0,end = 0;
find_maximum_subarray(a, 0, n - 1, start, end, max);
cout << max << endl;
}