輾轉相除法是計算兩個數最大公約數(Greatest conmmon divisor)的一種對數複雜度算法。
問題:有兩個正整數 x , y ,求 gcd(x,y):
算法證明:
設 x > y , 且 x = r + y * c , 其中 r >= 0, c >= 0 ;
1. if r = 0 then gcd( x,y) == y 爲結束條件)
2. if c = 0 then 算法沒有前進
3. if r > 0 && c >0 then r = x - c * y ,
易知 : 如果d 爲 x, y的公約數, 則必爲r = x - c*y 的公約數 ,即 x,y 的公約數必爲 y, r 的公約數;
如果e 爲 r和y的公約數, 有 r / e = x / e - c * y / e, r / e , c*y/e 爲正整數, x / e 也爲正整數,即y, r的公約數必爲x,y的公約數;
綜上,x,y的最大公約數等價於y, r的最大公約數由此易得遞歸算法:
int gcd ( int x, int y )
{
if( x < y )
swap( x, y );
int r = x % y;
if( r == 0 )
return y;
else
return gcd( y , r );
}
int main()
{
cout<< gcd( 9, 15 );
}
算法複雜度:設 x > y , 且 x = r + y * c , 其中 r = x % y , c > 0 ;
得:x > r *( c+1 ) > 2 * r ;
即: 經過兩次迭代, x至少縮小一倍,算法複雜度爲 2*log2(N);