to iterate is human, to reverse, divine. // 迭代乃人工, 遞迴顯神通。
雖說如此,但是我們發現很多時候我們用到的是迭代,而不是遞迴 ???
舉個栗子1.陣列求和
1.1迭代法
1int 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, intn)//t(n) = o(n)
2.陣列倒置
其實這個在c++裡有相應的函式,但是作為acmer,凡是用啥都得自己造 /堅強
2.1遞迴法
void reverse(int* a, int lo, inthi)
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, inthi)
else
}
//t(n) = o(n)
3.max
在區間 [lo, hi)裡找出最大的兩個整數a[x1] 和 a[x2] //a[x1] > a[x2]
要求元素比較次數盡可能的少
3.1迭代
1void 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...
二分思想和分治法
二分思想和分治法 如果你對概念很敏感,會馬上意識到這兩者的細微不同 二分搜尋每次都要捨棄一半,從留下的一半中尋找目標 而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大...
分治法的基本思想 高階排序演算法 分治法與歸併排序
很多有用的演算法結構上是遞迴的,為了解決乙個特定問題,演算法一次或者多次遞迴呼叫其自身以解決若干子問題。這些演算法典型地遵循分治法的思想 將原問題分解為幾個規模較小但是類似於原問題的子問題,遞迴求解這些子問題,然後再合併這些問題的解來建立原問題的解。分治法在每層遞迴時有三個步驟 現在我們就來看下歸併...