分治,字面上的解釋是「分而治之」,就是把乙個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。在電腦科學中,分治法就是運用分治思想的一種很重要的演算法。分治法是很多高效演算法的基礎,如排序演算法(快速排序,歸併排序)等。通俗來說就是把乙個大的方案,分解成乙個乙個小方案,再組織起來。
例如對100個元素排序,可以分解成 2 組50個元素的排序,再分解成 4 組25個元素的排序…最後分解成 50 組 2個元素的排序。最後再對已經有序的元素進行整合。
如上所示,歸併演算法是基於「分治」策略。即:要將乙個陣列排序,先(遞迴)將它分成兩半分別排序,然後將結果歸併起來。
歸併過程中,我們需要把兩個已經有序(同一陣列的前半部分和後半部分)的元素排列,歸併成乙個有序的元素排列。
上面的**和**即歸併排序中的「歸併」部分。將乙個無序的陣列從分解 到歸併 直至成為乙個有序的陣列,基於歸併思想,有兩種實現方法,分別是自頂向下的歸併排序和自底向上的歸併排序。// "歸併" 部分
public
static
void
main(string args) ;
aux=new
int[a.length];//初始化輔助陣列
merge(a,0,a.length/2-1,a.length-1);
}private
static
int aux;//需要輔助陣列,用來作比較
private
static
void
merge(int a, int lo, int mid, int hi)
for (int k = lo; k <= hi; k++)
else
if (j > hi)
else
if (aux[i] < aux[j]) else }}
遞迴實現的歸併排序是演算法設計中分治策略的典型應用。自頂向下的實現方式和android view的繪製機制的measure()
方法很相似,這裡穿插一下知識點:measure過程是後根遍歷(decorview最後setmeasurediemension()),所以子控制項的測量結果影響父控制項的測量結果。下面摘選《演算法4》中的來加深印象。
要對子陣列a[lo..hi]進行排序,先將它分為a[lo..mid]
和a[mid+1..hi]
兩部分,分別通過遞迴呼叫將它們單獨排序,最後將有序的子陣列歸併為最終的排序結果。1.首先我們把每個元素想象成乙個大小為 1 的陣列。(兩兩歸併)public
static
void
main(string args) ;
sort(a);
}private
static
int aux;// 需要輔助陣列,用來作比較
private
static
void
sort(int a)
private
static
void
sort(int a, int lo, int hi)
int mid = lo + (hi - lo) / 2;
sort(a, lo, mid);// 左半邊排序,裡面可能遞迴sort和merge方法
sort(a, mid + 1, hi);// 右半邊排序
merge(a, lo, mid, hi);// 歸併,merge方法如上
}
2.然後將兩個大小為2的陣列歸併成乙個有4個元素的陣列。(四四歸併)
3.然後再將2個大小為4的陣列歸併(八八歸併),如此下去。
歸併排序是穩定排序,速度僅次於快速排序,一般用於對總體無序,但是各子項相對有序的數列。
排序演算法 歸併排序
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...
排序演算法 歸併排序
include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...
排序演算法 歸併排序
歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...