对于maximum_subarray的分治算法:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
using namespace std;
int max_crossing_subarray(int A[], int low, int mid, int high, int& sub_low, int& sub_high)
{
int sum = 0;
int left_sum = INT_MIN, right_sum = INT_MIN;
int left_low, right_high;
int i;
for(i = mid; i>= low; i--)
{
sum += A[i];
if(left_sum < sum)
{
left_sum = sum;
left_low = i;
}
}
sum = 0;
for(i = mid; i<= high; i++)
{
sum += A[i];
if(right_sum < sum)
{
right_sum = sum;
right_high = i;
}
}
sum = left_sum + right_sum - A[mid];
sub_low = left_low;
sub_high = right_high;
return sum;
}
int max_subarray(int A[], int low, int high, int& sub_low, int& sub_high)
{
int sum = 0;
int mid = (low + high)/2;
if(low == high)
{
sum = A[low];
sub_low = sub_high = low;
return sum;
}
else
{
int sum1,sum2, sum3;
sum1 = max_subarray(A, low, mid, sub_low, sub_high);
int low1 = sub_low;
int high1 = sub_high;
sum2 = max_subarray(A, mid+1, high, sub_low, sub_high);
int low2 = sub_low;
int high2 = sub_high;
sum3 = max_crossing_subarray(A, low, mid, high, sub_low, sub_high);
int low3 = sub_low;
int high3 = sub_high;
if(sum3 > sum1 && sum3>sum2)
{
sub_low = low3;
sub_high = high3;
return sum3;
}
else
{
if(sum1 > sum2)
{
sub_low = low1;
sub_high = high1;
return sum1;
}
else
{
sub_low = low2;
sub_high = high2;
return sum2;
}
}
}
}
void main()
{
int A[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
int a;
int b;
int& sub_low = a;
int& sub_high = b;
cout<<max_subarray(A, 0, 15, sub_low, sub_high)<<endl;
cout<<sub_low<<endl;
cout<<sub_high<<endl;
}
其中要注意的是如何求跨边界的最大和子数组。我一开始认为跨边界最大子数组就是左边最大和开始的索引到右边最大和结束的索引之间的数的和,错误代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int max_subarray(int A[], int low, int high, int& sub_low, int& sub_high)
{
int sum = 0;
int mid = (low + high)/2;
if(low == high)
{
sum = A[low];
sub_low = sub_high = low;
return sum;
}
else
{
int sum1,sum2;
sum1 = max_subarray(A, low, mid, sub_low, sub_high);
int low1 = sub_low;
int high1 = sub_high;
sum2 = max_subarray(A, mid+1, high, sub_low, sub_high);
int low2 = sub_low;
int high2 = sub_high;
for(int i = low1; i<= high2; i++)
sum += A[i];
if(sum > sum1 && sum>sum2)
{
sub_low = low1;
sub_high = high2;
return sum;
}
else
{
if(sum1 > sum2)
{
sum = sum1;
sub_low = low1;
sub_high = high1;
//
cout<<sub_low<<" "<<sub_high<<" "<<sum<<endl;
//
return sum;
}
else
{
sum = sum2;
sub_low = low2;
sub_high = high2;
//
cout<<sub_low<<" "<<sub_high<<" "<<sum<<endl;
//
return sum;
}
}
}
}
void main()
{
int A[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
int a;
int b;
int& sub_low = a;
int& sub_high = b;
cout<<max_subarray(A, 0, 15, sub_low, sub_high)<<endl;
cout<<sub_low<<endl;
cout<<sub_high<<endl;
}
错在25-32行。