《演算法導論》 2 3 1分治法

2021-06-07 07:37:15 字數 1591 閱讀 9603

分治法

有很多演算法在結構上是遞迴的:為了解決乙個給定的問題,演算法要一次或多次地遞迴地呼叫其自身來解決相關的問題。這些演算法通常採用分治策略:將原問題劃分為n個規模較小而結構與原問題相似的子總是;遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解。

分治模式在每一層遞迴上都有三個步驟:

分解(divide):將原問題分解成一系列子總是

解決(conquer):遞迴地解各子問題,若子問題足夠小,則直接求解;

合併排序(merge sort)演算法完全依照了上述模式,直觀地操作如下:

分解:將n個元素分成各含n/2個元素的子串行;

解決:用合併排序法對兩個子串行以得到排序結果;

合併:合併兩個己排序的子串行以得到排序結果。

在對子序列排序時,其長度為1時遞迴結束,單個元素被視為是己排好序的。即其規模是足夠小的。

合併排序的關鍵步驟在於合併步驟中的合併兩個己排序子串行。為做合併,引入乙個輔助過程merge(a, p, q, r)其中a是個陣列,p、q和r是下標,滿足p<=q<=r。該過程假設子陣列a[p,q]和a[q+1,r]都己排好序,並將它們合併成乙個己排好序的子陣列代替當前子陣列a[p,r]。

下列為合併演算法偽**

其中賦值無窮大,是作為乙個「哨兵牌」。包含乙個特殊值。如int型中,如果要對其進行賦值無窮大,可以賦值乙個最大值。#include。中的int_max可以對其賦最大值。

而對其整個的排序,可以用偽**merge-sort(a,p,r)表示。

merge-sort(a,p,r):

if(pthenq=(p+r)/2向下取整。

merge-sort(a,p,q);

merge-sort(a,q+1,r);

merge(a,p,q,r);

#include

#include

#include

using namespace std;

//合併排序演算法,即陣列a中,從p到q下標的元素已經排序了,從q到j的元素也已經排序了,則將p到j的元素進行排序操作,

//注意,是從小到大排序。。正確,則輸出1;錯誤,則輸出-1

int merge(int *a,int p,int q,int j)

}for(int i = q+1;i

}if(p>q||q>j)

int n1 = q-p+2;

int n2 = j-q+1;

int *l = new int[n1];

int *r = new int[n2];

for(int k = 0;k

for(int k = 0;k

l[n1-1] = int_max;

r[n2-1] = int_max;

int i = 0;

int k = 0;

for(;p

else

}delete l;

delete r;

return 1;

}void merge_sort(int *a,int p,int r)

}void main()

;merge_sort(a,0,9);

for(int i = 0;i<10;i++)

cout<} 

演算法導論學習筆記 2 3 1分治法(歸併排序)

純翻譯 void merge ll a ll p,ll q,ll r else merge函式解析 假設a陣列的兩部分 乙個下標從p到q,乙個從q 1到r 已經排序好了,現在將這兩個排序好的部分陣列再排序,每次比較兩個子陣列的頭元素大小,小的插入,然後出佇列。因為有哨兵的存在,所以一定能排完。純翻譯...

2 3 1 分治法 歸併排序

分治法模式 分解原問題為若干子問題,這些子問題是原問題的規模較小的例項。解決這些子問題,遞迴地求解各子問題。然而,若子問題的規模足夠小,則直接求解。合併這些子問題的解成原問題的解。對於歸併排序 分解 分解待排序的n個元素的序列成各具n 2個元素的兩個子串行。解決 使用歸併排序遞迴地排序兩個子串行。合...

演算法(二) 分治法

分治法的適 條件 該問題的規模縮 到 定程度就可以容易地解決。該問題可以分解為若 個規模較 的相同問題 遞迴思想的應 該問題所分解出的各個 問題是相互獨 的,即 問題之間不包含公共的 問題。利 該問題分解出的 問題的解可以合併為該問題的解。案例 快排 1 過程 divide partition 對元...