辗转相除法证明及复杂度计算

辗转相除法是计算两个数最大公约数(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);



阅读更多
个人分类: 数据结构 c++
上一篇用栈实现Fibnacci递归过程的非递归算法
下一篇解决01背包问题的DP方法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭