演算法基礎 分治法(基於Python)

2021-09-11 05:25:30 字數 1622 閱讀 4797

有時候,你可能會遇到使用任何已知的演算法都無法解決的問題,這種時候,我們就可以試試分治法的思路。

分治法的基本思想很簡單,顧名思義,就是將乙個大問題分解為若干個子問題,然後我們逐一地解決這些子問題,將所有子問題解決完畢,也就將整體的大問題解決完畢了。

分治法的精髓:

分--將問題分解為規模更小的子問題;

治--將這些規模更小的子問題逐個擊破;

合--將已解決的子問題合併,最終得出「母」問題的解;

分治法的思路在具體操作時主要包括以下兩個步驟:

找出基線條件,這種條件必須盡可能簡單。

確定如何縮小問題的規模,然後不斷將問題分解(或者說縮小規模),直到符合基線條件。

舉個例子。給定乙個陣列,我們需要將該陣列的所有數字相加並返回結果。陣列如下所示:

2, 4, 6, 8

使用迴圈可以很容易地完成該任務:

def sum(arr):

total = 0

for x in arr:

total += x

return total

但是,分治法的思想是使用遞迴來完成該任務。通過遞迴的基線條件,我們將這個陣列數字累加的任務劃分成子問題,具體步驟如下:

第一步:找出基線條件。最簡單的陣列是什麼樣的呢?當然,如果陣列不包含任何元素或者只包含乙個元素,該陣列就是最簡單的了,計算該陣列的總和也就非常容易了。

所以,基線條件就是陣列不包含任何元素或者陣列只包含乙個元素。在不包含任何元素的情況下,陣列總和為0,而在只包含乙個元素的情況下,陣列總和即為該元素的數值。

第二步:每次遞迴呼叫都必須離空陣列更近一步。如何縮小問題規模呢?看下面的步驟:

首先,我們計算總和需要這樣做:

sum(2,4,6,8)=2+4+6+8=20

這種計算與下面的計算版本等效:

2+sum(4,6,8)=2+(4+6+8)= 2+18=20

在這裡呢,我們首先把第乙個元素2提取出來,然後計算剩下三個元素的總和為18,再把2和18相加同樣可以獲得結果20.

其次呢,對於後面三個數相加的結果,我們依然沿用該思路,我們首先把4提取出來,效果如下所示:

sum(4,6,8)=4+sum(6,8) =4+(6+8)=4+14=18

對於上面的計算式子,我們依然還是要對後面的兩個數字相加進行分解,將6提取出來,效果如下所示:

sum(6,8) = 6+sum(8)=6+8=14

當提取到上式時,最後進行sum運算的只剩下乙個元素8,這剛好符合了基線條件!而且在一次次地提取元素的過程中,我們傳遞給sum操作的運算元組越來越短,這就縮小了問題的規模了!

具體計算總和的**如下所示:

def sum_recurve(list):

if list ==

return 0

return list[0] + sum_recurve(list[1:])

當list陣列內部為空時返回0,否則將第乙個元素提取出來,計算除第乙個元素之外的其他數字的總和,然後與第乙個元素相加,再返回結果。

特別注意:編寫涉及陣列的遞迴函式時,基線條件通常情況下都是陣列為空或只包含乙個元素。程式設計陷入困境時,可以檢查基線條件是否設定正確。

演算法 分治法

include function 列印int型陣列 parameter int型陣列,陣列的長度 void displayarray int a,int n printf n function 劃分由下標s開始到t終止的int陣列 parameter int型陣列,陣列的起始座標,陣列的終點座標 r...

基礎演算法 合併排序(分治法)

基礎演算法 合併排序演算法 分治法 的宗旨是將問題 分解 處理 歸併 將書中的偽 翻譯為c c 語言實現,大致可用兩個函式來解決問題,第乙個函式實現 治 也就是分解問題,處理問題 的步驟,另乙個函式通 過遞迴實現 分 合 的操作。實現 分 治 的函式實現如下 void merge int parra...

五大基礎演算法 分治法

1 定義 分治法的主題思想就是分而治之,也就是說把乙個大原問題變成兩個或者多個小問題解決,最後把小問題的解合併起來就是原問題的解。分 將原問題分解為多個小問題 治 將這些小問題逐個解決 合 將小問題解合併,就得出原問題的解 2.演算法實現 a 分治法的正規化 分解問題 把原問題分解為若干個與原問題性...