欧几里得算法
在«几何原本»中,欧几里得提出了用辗转相除的方法求解两个整数(a,b)的最大公约数的算法:
gcd(a, b)
if (0 == b) return a
else return gcd(b, a mod b)
定理:若整数(a,b)的最大公约数为(gcd(a,b)),那么(gcd(a,b)=gcd(b,a\,mod\,b))
证明:
令(d)表示(a,b)的公约数,那么(d|a)且(d|b)
推出(d|(a\,mod\,b)=a-kb)
所以((a,b))和((b,a\,mod\,b))两者拥有的公约数集合是一样的
即得证
算法复杂度
欧几里得算法最多只会递归(Theta(log n))次,所以完全不用担心爆栈,证明如下:
引理:设(a>bgeq 1)并且(gcd(a,b))递归调用了(kgeq 1)次,那么(ageq f_{k+2},bgeq f_{k+1}),其中(f_k)表示第(k)项斐波那契数
证明:
这里用归纳法证明,当(k=1)时,(bgeq f_2=1,ageq f_3=2)成立
当(k>1)时,(bgeq f_{k+1},a\,mod\,bgeq f_{k})并且(ageq b+(a\,mod\,b)geq f_{k+1}+f_{k}=f_{k+2})
即得证
由于(f_kapprox frac{phi^k}{sqrt{5}}),其中(phi=frac{1+sqrt{5}}{2}),是呈几何倍数增长的,所以欧几里得算法复杂度为(Theta(log n))
扩展欧几里得算法
当要求解方程(a∗x+b∗y=gcd(a,b))的整数解的时候,只需要扩展一下欧几里得算法就可以得到整数解((x,y)):
exgcd(a, b, &x, &y)
if (0 == b)
x = 1 y = 0
return a
else
d = exgcd(b, a % b, &xx, &yy)
x = yy y = xx - a / b * yy
return d