分治法求最大子数组

 1 /**
 2  *分治法求最大子数组
 3  *yaoC 2014-09-06
 4  *Θ(nlg(n))
 5  */
 6 
 7 #include<iostream>
 8 using namespace std;
 9 
10 #define neg_infinity -999999
11 
12 //一个子数组的开始下标,结束下标和值的和
13 struct indices_and_value
14 {
15     int left;
16     int right;
17     int value;
18 };
19 
20 /**
21  * [findMaxCrossingSubarray 找到跨越中点的最大子数组]
22  * @param  A     [输入数组]
23  * @param  low   [数组开始下标]
24  * @param  mid   [数组中间下标]
25  * @param  heigh [数组结束下标]
26  * @return       [所求子数组的开始结束下标、值的和]
27  */
28 indices_and_value findMaxCrossingSubarray(int* A, int low, int mid, int heigh)
29 {
30     int sum = 0;
31     int left_sum = neg_infinity;//最大子数组在中点左边的值的和
32     indices_and_value p;
33     for (int i = mid; i >= low; i--)
34     {
35         sum += A[i];
36         if (sum>left_sum)
37         {
38             left_sum = sum;
39             p.left = i;
40         }
41     }
42     sum = 0;
43     int right_sum = neg_infinity;//最大子数组在中点右边的值的和
44     for (int i = mid + 1; i <= heigh; i++)
45     {
46         sum += A[i];
47         if (sum>right_sum)
48         {
49             right_sum = sum;
50             p.right = i;
51         }
52     }
53     p.value = left_sum + right_sum;
54     return p;
55 }
56 
57 /**
58  * [findMaxSubarray 找到非跨越中点的最大子数组]
59  * @param  A     [输入数组]
60  * @param  low   [数组开始下标]
61  * @param  heigh [数组结束下标]
62  * @return       [所求子数组的开始结束下标、值的和]
63  */
64 indices_and_value findMaxSubarray(int* A, int low, int heigh)
65 {
66     int mid = (low + heigh) / 2;//数组中点
67     indices_and_value p;
68     if (low == heigh)//base case:only one element
69     {
70         p.left = low;
71         p.right = low;
72         p.value = A[low];
73     }
74     else//recursive case
75     {
76         indices_and_value left = findMaxSubarray(A, low, mid);
77         indices_and_value cross = findMaxCrossingSubarray(A,low,mid,heigh);
78         indices_and_value right = findMaxSubarray(A,mid + 1,heigh);
79         if (left.value>cross.value)
80             p = left;
81         else
82         {
83             if (right.value>cross.value)
84                 p = right;
85             else p = cross;
86         }
87     }
88     return p;
89 }
90 
91 int main()
92 {
93     int test[] = { 013, -3, -2520, -3, -16, -231820, -712, -5, -2215, -47 };
94     indices_and_value p;
95     p = findMaxSubarray(test, 016);//(8,11,43)
96     cout <<"("<< p.left << "," << p.right << "," << p.value <<")"<< endl;
97 }
posted @ 2014-09-06 16:20  yaoC  阅读(665)  评论(0)    收藏  举报