1. 程式人生 > >輾轉相除法證明及其時間複雜度證明

輾轉相除法證明及其時間複雜度證明

首先看下輾轉相除法的遞迴及非遞迴程式碼實現:

<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
=1<=un-1, 又因為由uk mod uk+1=uk+2, 可得uk>=uk+1+uk+2, 由數學歸納法容易得到uk>=Fn-k, 於是得到a=u0>=Fn, b=u0>=Fn-1. 也就是說如果歐幾里得演算法需要做n次模運算, 則b必定不小於Fn-1. 換句話說, 若 b<Fn-1, 則演算法所需模運算的次數必定小於n. 根據菲波那契數列的性質, 有Fn-1>(1.618)n/sqrt(5), 即b>(1.618)n/sqrt(5), 所以模運算的次數為O(lgb).

如果有大神有更容易理解的證明,歡迎提出交流。