分治法求最大子数组

 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 }

你可能感兴趣的:(分治法)