分治法(思想篇)

2022-07-27 09:30:14 字數 2479 閱讀 4791

to iterate is human, to reverse, divine. // 迭代乃人工, 遞迴顯神通。

雖說如此,但是我們發現很多時候我們用到的是迭代,而不是遞迴 ???

舉個栗子1.陣列求和

1.1迭代法

1

int sum1(int a, intn)6

return sum; //

o(1)7}

8//無論 a 內容如何,都有:t(n) = 1 + n * 1 + 1 = o(n)

此處可用減而治之的思想//單調性

將原問題分成兩個子問題,

令其中乙個問題規模縮減,並治理,//未被加和的a[i]

另乙個問題規模不變,也進行治理,//每次加和的a[i]

最後將兩個子問題合併。

1.2線性遞迴法

void sum2(int a, int

n)//t(n) = o(n)

2.陣列倒置

其實這個在c++裡有相應的函式,但是作為acmer,凡是用啥都得自己造 /堅強

2.1遞迴法

void reverse(int* a, int lo, int

hi)

else

}

在此之外,我特地查了一下c++庫中reverse()的**

//

reverse algorithm example

#include //

std::cout

#include //

std::reverse

#include //

std::vector

intmain ()

//template

//void reverse (bidirectionaliterator first, bidirectionaliterator last)

////

} //用了乙個雙向迭代器,思路大致一樣

總的來說,就是乙個分而治之的思想

將原問題分解成兩個子問題,

同時進行治理,

最後合併治理。

由此我們是不是也能對剛剛第乙個陣列求和用這種方法呢

1.3二分遞迴法

void sum3(int a, int lo, int

hi)

else

}

//t(n) = o(n)

3.max

在區間 [lo, hi)裡找出最大的兩個整數a[x1] 和 a[x2]   //a[x1] > a[x2]

要求元素比較次數盡可能的少

3.1迭代

1

void max1(int a, int lo, int hi, int &x1, int &x2)67

} //比較了n - 1次

8for(x2 = lo, int i = lo + 1; i < x1; i++)

1213}14

for(int i = x1 + 1; i < hi; i++)18}

1920 } //

總共比較了2 * n - 3 次

我們不妨改變一下思路:先選 a[lo] 和a[lo + 1] 為基準找出兩者間最大數的下標給x1,最小數下標給x2,

然後讓a[x2] 和後面的元素比較,如果有比這個元素大的交換下標,

讓a[x2]再和a[x1]比較,如果比這個元素大,那麼再交換下標。

void max1(int a, int lo, int hi, int &x1, int &x2)

for(int i = lo + 2; i < hi; i++)}}

} //

best 比較了1 + (n - 2) * 1 = n - 1 次

//worst 比較了1 + (n - 2) * 2 = 2 * n - 3 次

似乎沒有改變最糟糕的情況

不妨遞迴 + 分治

仿照上面二分遞迴的方法

思路:在陣列兩邊選出x1l, x2l, x1r, x2r  // x1l  >  x2l, x1r  >  x2r  

比較兩個最大的x1l, x1r, 兩個中最大的即為x1

void max2(int a, int lo, int hi, int &x1, int &x2)

else

if(lo + 3 ==hi)

else

else

}} //

t(n) = 2 * t(n / 2) + 2 = 5 * n / 3 - 2

演算法思想筆記 分治法

1 合併排序 2 快速排序 3 折半查詢 4 二叉樹遍歷 5 大整數乘法和strassen乘法 6 最近對問題和凸包問題的分治解法 簡介 大整數乘法 把a的前半部分記為a1,後半部分極為a0 b的前半部分記為b1,後半部分記為b0 即a a1 10 n 2 a0 b b0 10 n 2 b0 則有c...

二分思想和分治法

二分思想和分治法 如果你對概念很敏感,會馬上意識到這兩者的細微不同 二分搜尋每次都要捨棄一半,從留下的一半中尋找目標 而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大...

分治法的基本思想 高階排序演算法 分治法與歸併排序

很多有用的演算法結構上是遞迴的,為了解決乙個特定問題,演算法一次或者多次遞迴呼叫其自身以解決若干子問題。這些演算法典型地遵循分治法的思想 將原問題分解為幾個規模較小但是類似於原問題的子問題,遞迴求解這些子問題,然後再合併這些問題的解來建立原問題的解。分治法在每層遞迴時有三個步驟 現在我們就來看下歸併...