➢分治法(divide and conquer, d&c) :將原問題劃分成若干個規模較小而結構與原問題一致的子問題;遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解。
➢容易確定執行時間,是分治演算法的優點之一。
➢分治模式在每- -層遞迴上都有三個步驟:
-分解(divide) :將原問題分解成一系 列子問題;
-解決(conquer) :遞迴地解各子問題。若子問題足夠小,則直接有解;
-合併(combine):將子問題的結果合併成原問題的解。
➢原問題可以一 直分解為形式相同子問題,當子問題規模較小時,可自然求解 ,如乙個元素本身有序
➢子問題的解通過合併可以得到原問題的解
➢子問題的分解以及解的合併一定是比較簡單的 ,否則分解和合併所花的時間可能超出暴力解法,得不償失
快排:劃分 歸併:合併
➢一遍單向掃瞄法:
-一遍掃瞄法的思路是,用兩個指標將陣列劃分為三個區間,
-掃瞄指標(scan_ pos)左邊是確認小於等於主元的,
-掃瞄指標到某個指標(next_ bigger_ pos)中間為未知的,因此我們將第二個指標(next_ bigger_pos) 稱為未知區間末指標,末指標的右邊區間為確認大於主元的元素
邊界:如果最後乙個掃瞄元素大於主元,bigger左移之後小於了scanner
如果最後乙個掃瞄的元素小於主元,scanner的右移導致, scanner大於bigger
➢雙向掃瞄的思路是,頭尾指標往中間掃瞄,從左找到大於主元的元素,從右找到小於等於主元的元素二者交換,繼續掃瞄,直到左側
無大元素,右側無小元素
/*快排*/
void swap(int a, int a, int b)
/*單項掃瞄分割槽法*/
int partition(int a, int p, int r)
}////最終bigger指向的元素以及左邊的元素都比主元小
//sp指向的元素以及右邊的元素都比主元大
swap(a, p, bigger);//交換後主元右邊的元素都比主元小,左邊的元素都比主元大。
return bigger;
}/*雙向掃瞄分割槽法*/
int partition2(int a, int p, int r)
swap(a,p,right);//最終右指標指向的元素一定是位於最左邊小於主元的第乙個元素
return right;
}void quicksort(int a, int p, int r)
}
小於主元,s位置和e位置交換,e++, s++
等於土元,s++
大於主元,s和bigger交換, bigger--
快排中的優化主要是對分割槽函式的優化,排序函式無法進行優化。優化的主要思想是盡可能讓每次分割槽都讓主元的大小處於中間位置。只有主元找好了,才能接近o(nlgn)的時間複雜度。
/*雙向掃瞄分割槽法-三點中值法改進*/
int partition2(int a, int p, int r)else if(a[r] <= a[midindex] && a[r] >= a[p])else
swap(a, p , midvalueindex);
int pivot = a[p];//主元
int left = p+1;//左掃瞄指標
int right = r;//右掃瞄指標
while(left <= right)
swap(a,p,right);//最終右指標指向的元素一定是位於最左邊小於主元的第乙個元素
return right;
}void quicksort(int a, int p, int r)
}
多增加的優化部分時間複雜度為o(1)。
2、絕對中值法
將陣列每五個分成一組,最後一組不足5也沒關係,利用插入排序選出每組的中值構成相對中值陣列,再對相對中值陣列進行插入排序,選出相對中值陣列中的中值,這個值就是絕對中值。這個演算法的複雜度為o(n),且演算法較為複雜。一般選擇三點中值法居多。
3、待排序列表較短時,用插入排序
雖然插入排序的時間複雜度是o(n^2),但實際上是n(n-1)/2,而快排是2n(lgn+1)。所以在n不太大的情況下,使用插入排序反而能減少時間開銷。
利用歸併排序學習分治法。
➢歸併排序(merge sort)演算法完全依照了分治模式
-分解:將n個元素分成各含n/2個元素的子串行;
-解決:對兩個子串行遞迴地排序;
-合併:合併兩個已排序的子串行以得到排序結果
➢和快排不同的是
-歸併的分解較為隨意
-重點是合併
演算法思想 分治演算法
分而治之 大問題能夠拆成相似的小問題,記住這些小問題需要具有相似性。而後將小問題的每個解合成為大問題的解。所以說大問題如何拆,小問題如何合併才是這個演算法最主要的乙個思想。實際上很多演算法如貪心演算法,動態規劃等等都是要求把大問題拆成小問題。而分治演算法的重要一點就是要適用於能夠重新把小問題的解合併...
分治演算法思想
1.分解 對這k個子問題分別求解。如果子問題的規模仍然不夠小,則再劃分為k個子問題,如此遞迴的進行下去,直到問題規模足夠小,很容易求出其解為止。2.合併 將求出的小規模的問題的解合併為乙個更大規模的問題的解,自底向上逐步求出原來問題的解。3.分治演算法的使用條件 分治法所能解決的問題一般具有以下幾個...
分治演算法思想介紹
一,介紹 分治演算法主要包含兩個步驟 分 治。分,就是遞迴地將原問題分解成小問題 治則是 在解決了各個小問題之後 各個擊破之後 合併小問題的解,從而得到整個問題的解 二,分治遞迴表示式 分治演算法一般都可以寫出乙個遞迴表示式 比如經典的歸併排序的遞迴表示式 t n 2t n 2 o n t n 代表...