(一) 分治算法

- 基本思想
- 適用情況
- 基本步驟
- 程序設計
  - 思維過程
  - 一般的算法設計模式
  - 復雜度
- 經典運用

# 基本思想:


  1. 字面上的解釋是“分而治之”惭嚣,就是將一個規(guī)模為N的問題分解為K個規(guī)模較小的子問題( 反復分解直到問題小到可直接求解為止)遵湖,使這些子問題相互獨立可分別求解,再將k個子問題的解合并成原問題的解晚吞。

    • 這些子問題相互獨立且與原問題性質相同(規(guī)模一般也相同)延旧。只要求出子問題的解,合并就可得到原問題的解槽地。
  2. 在分治法中迁沫,子問題的解法通常與原問題相同芦瘾。這自然導致 遞歸過程
    分治與遞歸像一對孿生兄弟集畅,經常同時應用在算法設計之中近弟,并由此產生許多高效算法。

# 適用情況


分治法能解決的問題一般具有以下4個特征:
(1)當問題的規(guī)哪嫡縮小到一定的程度就可以容易地解決藐吮。
(2)問題可以分解為若干個規(guī)模較小的問題溺拱,即該問題具有最優(yōu)子結構性質逃贝。
(3)利用該問題分解出的子問題的解可以合并為該問題的解(關鍵);
(4)各個子問題是相互獨立的迫摔,即子問題之間不包含公共的子問題沐扳。

  • 第一條特征是絕大多數問題都可以滿足的,因為問題的計算復雜性一般是隨著問題規(guī)模的增加而增加句占;
  • 第二條特征是應用分治法的前提,它也是大多數問題可以滿足的沪摄,此特征反映了遞歸思想的應用;
  • 第三條特征是關鍵纱烘,能否利用分治法完全取決于問題是否具有第三條特征杨拐,如果具備了第一條和第二條特征,而不具備第三條特征擂啥,則可以考慮用貪心法或動態(tài)規(guī)劃法哄陶。
  • 第四條特征涉及到分治法的效率,如果各子問題是不獨立的則分治法要做許多不必要的工作哺壶,重復地解公共的子問題屋吨,此時雖然可用分治法,但一般用動態(tài)規(guī)劃法較好山宾。

這個思想是很多高效算法的基礎至扰,在各種排序方法中,如:歸并排序资锰、堆排序敢课、快速排序等,都存在有分治的思想绷杜。還有傅立葉變換(快速傅立葉變換)等

# 基本步驟:


  1. 分解翎猛,將要解決的問題劃分成若干個規(guī)模較小的同類問題
  2. 求解,當子問題劃分得足夠小時接剩,用較簡單的方法解決
  3. 合并切厘,按原問題的要求,將子問題的解逐層合并構成原問題的解


    分治

要點:

  • 分幾個懊缺?子問題規(guī)模多大疫稿? 最好使子問題的規(guī)模大致相同培他。即將一個問題分成大小相等的 k 個子問題的處理方法是行之有效的。
  • 子問題如何求解?
  • 合并原問題的解?
  • 分析時間復雜性

# 程序設計


## 依據分治法設計程序時的思維過程

實際上就是類似于數學歸納法遗座,找到解決本問題的求解方程公式舀凛,然后根據方程公式設計遞歸程序。

  1. 一定是先找到最小問題規(guī)模時的求解方法
  2. 然后考慮隨著問題規(guī)模增大時的求解方法
  3. 找到求解的遞歸函數式后(各種規(guī)耐窘或因子)猛遍,設計遞歸程序即可。
    分治的算法思想與遞歸往往是相伴而生的
## 一般的算法設計模式如下:
Divide-and-Conquer(P)

1. if |P|≤n0
2. then return(ADHOC(P))
3. 將P分解為較小的子問題 P1 ,P2 ,…,Pk
4. for i←1 to k
5. do yi ← Divide-and-Conquer(Pi) △ 遞歸解決Pi
6. T ← MERGE(y1,y2,…,yk) △ 合并子問題
7. return(T)

其中:
    |P|表示問題P的規(guī)模号坡;
    n0為一閾值懊烤,表示當問題P的規(guī)模不超過n0時,問題已容易直接解出宽堆,不必再繼續(xù)分解腌紧。
    ADHOC(P)是該分治法中的基本子算法,用于直接解小規(guī)模的問題P畜隶。因此壁肋,當P的規(guī)模不超過n0時直接用算法ADHOC(P)求解。
    算法MERGE(y1,y2,…,yk)是該分治法中的合并子算法籽慢,用于將P的子問題P1 ,P2 ,…,Pk的相應的解y1,y2,…,yk合并為P的解浸遗。
## 復雜度
  • 一個分治法將規(guī)模為n的問題分成k個規(guī)模為n/m的子問題去解。設分解閥值n0=1箱亿,且adhoc解規(guī)模為1的問題耗費1個單位時間跛锌。再設將原問題分解為k個子問題以及用merge將k個子問題的解合并為原問題的解需用f(n)個單位時間。用T(n)表示該分治法解規(guī)模為|P|=n的問題所需的計算時間极景,則有:
    T(n) = kT(n/m)+f(n)

  • 通過迭代法求得方程的解:
    遞歸方程及其解只給出n等于m的方冪時T(n)的值察净,但是如果認為T(n)足夠平滑,那么由n等于m的方冪時T(n)的值可以估計T(n)的增長速度盼樟。通常假定T(n)是單調上升的氢卡,從而
    mi≤n<mi+1時,T(mi)≤T(n)<T(mi+1)

# 經典運用:


  • 二分查找
  • 合并(歸并)排序
  • 快速排序
  • 最大子段和
  • 最近對
  • 凸包
  • 漢諾塔
  • 大數相乘問題
  • 比賽日程安排
  • 尋找假幣問題
  • Strassen矩陣乘法
  • 棋盤覆蓋
  • 線性時間選擇
    ...
//示例代碼:二分查找
#include <stdio.h>
 
int bin_search(int A[], int n, int key)
{
    int low = 0, high = 0, mid = 0;
    high = n - 1;
    while (low <= high) {
        mid = (low + high) / 2;
        if (A[mid] == key) { //查找成功晨缴,返回mid
            return mid;
        }
        if (A[mid] < key) { //在后半序列中查找
            low = mid + 1;
        }
        if (A[mid] > key) { //在前半序列中查找
            high = mid - 1;
        }
    }
    return -1; //查找失敗
}
 
int main(int argc, const char * argv[]) {
    // insert code here...
    int A[10] = {2, 3, 5, 7, 8, 10, 12, 15, 19, 21};
    int i = 0, n = 0, addr = 0;
    printf("The contents of the Array A[10] are\n");
    for (i = 0; i < 10; i++) {
        printf("%d ",A[i]); //顯示數組A中的內容
    }
    printf("\nPlease input a interger for search\n");
    scanf("%d", &n); //輸入待查找得元素
    addr = bin_search(A, 10, n); //折半查找译秦,返回該元素在數組中的下標
    if (-1 != addr) {
        printf("%d is at the %dth unit is array A\n", n, addr);
    }else{
        printf("There is no %d in array A\n", n); //查找失敗
    }
    getchar();
     
    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市击碗,隨后出現的幾起案子筑悴,更是在濱河造成了極大的恐慌,老刑警劉巖稍途,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阁吝,死亡現場離奇詭異,居然都是意外死亡械拍,警方通過查閱死者的電腦和手機突勇,發(fā)現死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門装盯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甲馋,你說我怎么就攤上這事埂奈。” “怎么了定躏?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵账磺,是天一觀的道長。 經常有香客問我痊远,道長垮抗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任拗引,我火速辦了婚禮借宵,結果婚禮上幌衣,老公的妹妹穿的比我還像新娘矾削。我一直安慰自己,他們只是感情好豁护,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布哼凯。 她就那樣靜靜地躺著,像睡著了一般楚里。 火紅的嫁衣襯著肌膚如雪断部。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天班缎,我揣著相機與錄音蝴光,去河邊找鬼。 笑死达址,一個胖子當著我的面吹牛蔑祟,可吹牛的內容都是我干的。 我是一名探鬼主播沉唠,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼疆虚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了满葛?” 一聲冷哼從身側響起径簿,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘀韧,沒想到半個月后篇亭,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡锄贷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年译蒂,在試婚紗的時候發(fā)現自己被綠了鄙币。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹂随,死狀恐怖十嘿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情岳锁,我是刑警寧澤绩衷,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站激率,受9級特大地震影響咳燕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜乒躺,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一招盲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘉冒,春花似錦欣尼、人聲如沸翁狐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驻子。三九已至琐脏,卻和暖如春首繁,著一層夾襖步出監(jiān)牢的瞬間践宴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工究驴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镊绪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓洒忧,卻偏偏與公主長得像蝴韭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子跑慕,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內容

  • 分治算法 一万皿、基本概念 在計算機科學中,分治法是一種很重要的算法核行。字面上的解釋是“分而治之”牢硅,就是把一個復雜的問題...
    木葉秋聲閱讀 5,292評論 0 3
  • 分治算法 一、基本概念 在計算機科學中芝雪,分治法是一種很重要的算法减余。字面上的解釋是“分而治之”,就是把一個復雜的問題...
    Java資訊庫閱讀 9,767評論 0 14
  • https://www.cnblogs.com/steven_oyj/archive/2010/05/22/174...
    麒麟楚莊王閱讀 572評論 0 0
  • 五大常用算法之一:分治算法 一惩系、基本概念 在計算機科學中位岔,分治法是一種很重要的算法如筛。字面上的解釋是“分而治之”,就...
    鮑陳飛閱讀 1,240評論 0 4
  • http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741...
    RavenX閱讀 455評論 0 1