4.1 最大子数组问题
#include <common.h>
//FIND-MAX-CROSSING-SUBARRAY
static void find_max_crossing_subarray(
__in const int *A,
__in int low,
__in int mid,
__in int high,
__out int *max_left_index,
__out int *max_right_index,
__out int *max_sum)
{
int left_sum = INT_MIN, right_sum = INT_MIN;
int sum = 0;
int i, l, r;
for (i= mid; i >= low; --i) {
sum = sum + A[i];
if (sum > left_sum) {
left_sum = sum;
l = i;
}
}
sum = 0;
for (i = mid + 1; i <= high; ++i) {
sum = sum + A[i];
if (sum > right_sum) {
right_sum = sum;
r = i;
}
}
*max_left_index = l;
*max_right_index = r;
*max_sum = left_sum + right_sum;
TRACE("%s: in (%d, %d, %d) out (%d, %d, %d)\n",
__FUNCTION__,
low, mid, high,
*max_left_index,
*max_right_index,
*max_sum);
}
//FIND-MAXIMUM-SUBARRAY
static void find_max_subarray(
__in const int *A,
__in int low,
__in int high,
__out int *max_left_index,
__out int *max_right_index,
__out int *max_sum
)
{
int mid = 0;
int l_l, l_r, l_s; //left_left_index; ..
int r_l, r_r, r_s; //right_left_index; ..
int c_l, c_r, c_s; //cross_left_index; ..
if (high == low) {
*max_left_index = low;
*max_right_index = high;
*max_sum = A[low];
goto l_exit;
}
mid = (low + high)/2;
find_max_subarray(
A,low, mid,
&l_l, &l_r, &l_s);
find_max_subarray(
A, mid+1, high,
&r_l, &r_r, &r_s);
find_max_crossing_subarray(
A, low, mid, high,
&c_l, &c_r, &c_s);
if (c_s >= l_s && c_s >= r_s) {
*max_left_index = c_l;
*max_right_index = c_r;
*max_sum = c_s;
goto l_exit;
}
if (l_s >= r_s) {
*max_left_index = l_l;
*max_right_index = l_r;
*max_sum = l_s;
goto l_exit;
}
*max_left_index = r_l;
*max_right_index = r_r;
*max_sum = r_s;
l_exit:
TRACE("%s: in (%d, %d) out (%d, %d, %d)\n",
__FUNCTION__,
low, high,
*max_left_index,
*max_right_index,
*max_sum);
}
void func_4_1(void)
{
const int A[] = {
13, -3, -25, 20, -3, -16, -23, 18,
20, -7, 12, -5, -22, 15, -4, 7
};
int l, r, sum;
find_max_subarray(
A, 0, sizeof(A)/sizeof(int) -1,
&l, &r, &sum);
TRACE("%s: (%d, %d, %d)\n",
__FUNCTION__,
l, r, sum);
}
输出结果:
《算法导论》
=========第四章 分治策略=========
find_max_subarray: in (0, 0) out (0, 0, 13)
find_max_subarray: in (1, 1) out (1, 1, -3)
find_max_crossing_subarray: in (0, 0, 1) out (0, 1, 10)
find_max_subarray: in (0, 1) out (0, 0, 13)
find_max_subarray: in (2, 2) out (2, 2, -25)
find_max_subarray: in (3, 3) out (3, 3, 20)
find_max_crossing_subarray: in (2, 2, 3) out (2, 3, -5)
find_max_subarray: in (2, 3) out (3, 3, 20)
find_max_crossing_subarray: in (0, 1, 3) out (0, 3, 5)
find_max_subarray: in (0, 3) out (3, 3, 20)
find_max_subarray: in (4, 4) out (4, 4, -3)
find_max_subarray: in (5, 5) out (5, 5, -16)
find_max_crossing_subarray: in (4, 4, 5) out (4, 5, -19)
find_max_subarray: in (4, 5) out (4, 4, -3)
find_max_subarray: in (6, 6) out (6, 6, -23)
find_max_subarray: in (7, 7) out (7, 7, 18)
find_max_crossing_subarray: in (6, 6, 7) out (6, 7, -5)
find_max_subarray: in (6, 7) out (7, 7, 18)
find_max_crossing_subarray: in (4, 5, 7) out (5, 7, -21)
find_max_subarray: in (4, 7) out (7, 7, 18)
find_max_crossing_subarray: in (0, 3, 7) out (3, 4, 17)
find_max_subarray: in (0, 7) out (3, 3, 20)
find_max_subarray: in (8, 8) out (8, 8, 20)
find_max_subarray: in (9, 9) out (9, 9, -7)
find_max_crossing_subarray: in (8, 8, 9) out (8, 9, 13)
find_max_subarray: in (8, 9) out (8, 8, 20)
find_max_subarray: in (10, 10) out (10, 10, 12)
find_max_subarray: in (11, 11) out (11, 11, -5)
find_max_crossing_subarray: in (10, 10, 11) out (10, 11, 7)
find_max_subarray: in (10, 11) out (10, 10, 12)
find_max_crossing_subarray: in (8, 9, 11) out (8, 10, 25)
find_max_subarray: in (8, 11) out (8, 10, 25)
find_max_subarray: in (12, 12) out (12, 12, -22)
find_max_subarray: in (13, 13) out (13, 13, 15)
find_max_crossing_subarray: in (12, 12, 13) out (12, 13, -7)
find_max_subarray: in (12, 13) out (13, 13, 15)
find_max_subarray: in (14, 14) out (14, 14, -4)
find_max_subarray: in (15, 15) out (15, 15, 7)
find_max_crossing_subarray: in (14, 14, 15) out (14, 15, 3)
find_max_subarray: in (14, 15) out (15, 15, 7)
find_max_crossing_subarray: in (12, 13, 15) out (13, 15, 18)
find_max_subarray: in (12, 15) out (13, 15, 18)
find_max_crossing_subarray: in (8, 11, 15) out (8, 15, 16)
find_max_subarray: in (8, 15) out (8, 10, 25)
find_max_crossing_subarray: in (0, 7, 15) out (7, 10, 43)
find_max_subarray: in (0, 15) out (7, 10, 43)
func_4_1: (7, 10, 43)