最大子陣列是陣列a的和最大的非空連續子陣列。只有當陣列中包含負數時,最大子陣列問題才有意義。注意將實際問題轉化為數學問題!
使用分治策略的求解方法:
為尋找a[low..high]的最大子陣列,其**位置記為mid,然後考慮求解兩個子陣列a[low..mid]和a[mid+1..high]。a[low..high]的任何子陣列a[i..j]所處的位置必然是以下三種情況之一:
1. 完全位於子陣列a[low..mid]中,因此low <= i<= j <=mid。
2. 完全位於子陣列a[mid+1..high]中,因此mid < i<= j <= high。
3. 跨越了中點,因此low <= i <= mid < j <= high。
實際上,a[low..high]的最大子陣列必然是以上三種情況下所有子陣列中的最大者。
任何跨越中點的子陣列都由兩個子陣列a[i..mid]和a[mid+1..j]組成,只需分別找出a[i..mid]和a[mid+1..j]的最大子陣列,然後將其合併即可。
以下偽**接收陣列a和下標low,mid和high作為輸入,返回乙個下標元組劃定跨越中點的最大子陣列的邊界,並返回最大子陣列中值的和。
find-max-crossing-subarray(a, low, mid,high)
left-sum = - //儲存目前為止最大的和
sum = 0 //儲存a[i..mid]中所有值的和
for i = mid downto low
sum = sum + a[i]
ifsum > left-sum //每當找到乙個子陣列a[i..mid]的和大於left-sum
left-sum = sum //將left-sum更新為該子陣列的和
max-left = i //更新變數max-left來記錄當前下標i
right-sum = -
sum = 0
for j = mid + 1 to high
sum = sum + a[j]
ifsum > right-sum
right-sum = sum
max-right = j
return (max-left, max-right, left-sum +right-sum)
求解最大子陣列問題的分治演算法的偽**如下:
find-maxinum-subarray(a, low, high)
if high == low //子陣列只有乙個元素的情況
return(low,high,a[low])
else mid = //劃分子陣列,計算中點下標mid
//遞迴求解左右子陣列中的最大子陣列
(left-low,left-high,left-sum)= find-maxinum-subarray(a, low, mid)
(right-low,right-high,right-sum)= find-maxinum-subarray(a, mid+1, high)
//求跨越中點的最大子陣列
(cross-low,cross-high,cross-sum)= find-max-crossing-subarray(a,low,mid,high)
// 檢測最大子陣列位於左子陣列,右子陣列還是跨越中點的陣列
ifleft-sum >= right-sum and left-sum >= cross-sum
return(left-low,left-high,left-sum)
elseifright-sum >= left-sum and right-sum >= cross-sum
return(right-low,right-high,right-sum)
elsereturn(cross-low,cross-right,cross-sum)
對應的c++程式**如下:
#include
int find_max_crossing_subarray(int *a,intlow,int mid,int high,int& max_left,int& max_right,int& max_value)
} intright_sum = -1000000;//不可能的最小值
sum=0;
for(intj=mid+1;j
} max_value= left_sum+right_sum;
return0; }
int find_maximum_subarray(int *a,intlow,int high,int& max_left,int& max_right,int& max_value)
else
elseif((tmp_right_sum>=tmp_left_sum)&&(tmp_right_sum>=tmp_cross_sum))
else
} return0; }
int b[16] =;
int main()
最大子陣列問題 演算法導論
分治法思想 分解 子陣列一定被原陣列左邊或者右邊包含,或者跨越原陣列mid下標。解決 前兩種完全包含的情況形成子問題遞迴求解,並且縮小了問題規模,後一種是我們要解決的問題。合併 剩餘的問題是求跨越mid的最大子陣列,並且從三種情況中選出和最大的。另外 算導中偽 返回的是三元組,這裡實現的話用結構體返...
演算法導論 最大子陣列
之前都在準備考試,寒假還是繼續學習。除了家裡打掃衛生,似乎也確實沒什麼事。多看書,多寫 總能提高的。堅持。這次學到了函式返回值可以是乙個結構體,當我們要返回多個值的時候,就可以返回結構體。還有就是對分治法有了更深的認識。include typedef struct op op findmaxcros...
演算法導論3 最大子陣列問題 2016 1 3
頂著期末複習的壓力,還是在今天過完之前看完了乙個演算法 最大子陣列問題。演算法導論 中引入這個問題是通過 的購買與 經過問題轉換 換的過程比較簡單,但是不好想 將前一天的當天的 差價重新表示出來,即轉為了乙個最大子陣列的問題 具體內容是 13,3,25,20,3,16,23,18,20,7,12,5...