輾轉相除法證明及其時間複雜度證明
阿新 • • 發佈:2019-02-08
首先看下輾轉相除法的遞迴及非遞迴程式碼實現:
<span style="font-size:18px;">//遞迴實現
int gcd(int a,int b) {
return b?gcd(b,a%b):a;
} </span>
<span style="font-size:18px;">//非遞迴實現
int gcd(int a,int b)
{
int t;
while(b)
{
t = a;
a = b;
b = t%b;
}
return a;
}</span>
程式碼實現不難,不過怎麼證明呢?
其實從遞迴程式碼不難看出只要證明gcd(a,b) = gcd(b,a%b)取餘即可。
我們知道有這樣一個等式:a = b*q+r,那麼r = a-b*q = d(m-n*q),所以顯然a,b的最大公約數d也是r的因數,所以b,r 必有一個約數d,那麼為什麼d一定是b,r的最大公約數呢?
回過頭來看a = b*q+r,我們可以採用反證法,假設存在D>d為b,r的公約數,那麼顯然a,b的最大公約數就變為D了,與a,b的最大公約數為d矛盾,所以b,r的最大公約數也為d.這樣正如上面所示通過遞迴就很容易實現相應演算法了。
下面我們再來看下輾轉相除法的時間複雜度。
網上查了下時間複雜度為log2(n),不過證明好像挺麻煩的,對於我這種數學渣渣,,,更是如此。。。
下面證明轉載自:http://blog.sina.com.cn/s/blog_647d97b10100lf7k.html
注:如有侵權聯絡我刪除
我們先不考慮模運算本身的時間複雜度(算術運算的時間複雜度在Knuth的TAOCP中有詳細的討論), 我們只考慮這樣的問題: 歐幾里得演算法在最壞情況下所需的模運算次數和輸入的a和b的大小有怎樣的關係? 我們不妨設a>b>=1(若a<b我們只需多做一次模運算, 若b=0或a=b模運算的次數分別為0和1), 構造數列{un}: u0=a, u1=b, uk=uk-2 mod uk-1(k>=2), 顯然, 若演算法需要n次模運算, 則有un=gcd(a, b), un+1=0. 我們比較數列{un}和菲波那契數列{Fn}, F0=1<=un, F1如果有大神有更容易理解的證明,歡迎提出交流。