演算法導論之三最大子陣列問題

2021-06-25 08:54:03 字數 2515 閱讀 6768

最大子陣列是陣列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...