欧几里得算法的时间复杂度

欧几里得算法, 又称辗转相除法, 用于求两个自然数的最大公约数. 算法的思想很简单, 基于下面的数论等式

gcd(a,
b) = gcd(b, a mod b)

其中gcd(a, b)表示a和b的最大公约数, mod是模运算, 即求a除以b的余数. 算法如下:

输入: 两个整数a, b

输出: a和b的最大公约数

function gcd(a,
b:integer):integer;

   if
b=0 return a;

   else
return gcd(b, a mod b);

end
function

欧几里得算法是最古老而经典的算法, 理解和掌握这一算法并不难, 但要分析它的时间复杂度却并不容易.
我们先不考虑模运算本身的时间复杂度(算术运算的时间复杂度在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).

欧几里得算法的时间复杂度

时间: 2024-11-05 23:24:20

欧几里得算法的时间复杂度的相关文章

欧几里得算法实现、正确性证明及时间复杂度分析

求最大公约数的最常用的算法是欧几里得算法,也称为辗转相除法.问题定义为求i和j的最大公约数gcd(i,j),其中i和j是整数,不妨设i>j.算法可以递归的表示: 1.如果j能整除i,那么gcd(i,j)=j; 2.j不能整除i,令r=i%j,那么gcd(i,j)=gcd(j,r). 上面的算法对于i<j的情况也是可以的,实际上是做了一次交换. 使用C语言实现: int gcd(int i, int j) { int r = i % j; return r == 0 ? j : gcd(j, r

扩展欧几里得算法的模板实现

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组ax+by=gcd(a,b),求他的一组整数解 先给出实现代码 void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0;//gcd(a,0)显然等于1*a-0*0=a return a; } int ans=exgcd(b,a%b,x,y); int tem=x; x=y; y-=tem-(a/b)*y; return ans;} 但实

最大公约数-----欧几里得算法

欧几里得算法: 如果求两个数的最大公约数,那么最一般的求法是设置一个变量i=1,然后i不断加一,如果i加到某个数后两个数都能整除这个数了,然后把这个变量保存下来,然后最后的结果中最大的就是最大公约数. 然而这种方法时间复杂度可想而知有多高,所以一般情况瞎并不用这种方法,那么就有下面的欧几里得算法: 输入:两个数 a,b 输出:两个数的最大公约数 c 欧几里得算法:(1)找出两个数中最大的和最小的,分别为tmax.tmin, (2)不断令设置一个变量t代表tmin,tmin赋值为tmax  mod

欧几里得算法求两个整数的最大公因数

unsigned int Gcd (unsigned int m,unsigned int n){ unsigned int rem; while(n>0){ rem = m % n; m = n; n = rem; } return m; } 对于m<n的情况,第一次循环m,n会交换 算法的时间复杂度计算 时间复杂度 logn 若M > N,则第一次循环交换M和N. 若想分析其时间复杂度,则要求循环次数,即生成余数的次数. 可以证明: 当M > N, 则M % N < M

欧几里得算法--辗转相除法

今天在做一个很简单的算法题目,“求最大公约数和最小公倍数”.一看,太tm容易. 思考过程是这样的: 1.最大公约数,有两个个极端,一个是最大公约数是1,一个最大公约数是两个数之间较小的那个数. 2.我就理所当然地认为,so easy.不就一个for循环吗?从较小的那个数到1的这一段范围就,如果其中一个数能被较大的数整除不就ok罗,然后返回到那个数,不就得到最大公约数啦. 3.然后兴致冲冲地写下下列的代码 public static void commonDivisor(int n,int m)

扩展欧几里得算法求解不定方程【例 poj 1061】

扩展欧几里得算法是数论当中一种常用的算法,他可以用如下的姿势来表达: 设a, b为不全为0的整数,则存在整数x和y,使得 gcd(a, b) = a*x + b*y. 证明就略去. 树上还有一个拉梅定理:用欧几里得算法计算两个正整数的最大公因子时,所需要的除法次数不会超过两个整数中较小的那个十进制数的倍数的5倍. 拉梅定理的一个推论:求两个正整数a, b, a > b的最大公因子需要O(log2a)3次的位运算. 至于拉梅定理有什么用,暂时还没有研究=—=. 例1 求225和21的最大公因子s,

欧几里得算法:从证明等式gcd(m, n) = gcd(n, m mod n)对每一对正整数m, n都成立说开去

写诗或者写程序的时候,我们经常要跟欧几里得算法打交道.然而有没要考虑到为什么欧几里得算法是有效且高效的,一些偏激(好吧,请允许我用这个带有浓重个人情感色彩的词汇)的计算机科学家认为,除非程序的正确性在数学上得到了完全严格的证实,否则我们不能认为程序是正确的.既然存在即合理,因此下面我就详细得解说一下欧几里得算法,它为什么是正确的算法(算法过程就不给出了,有了思想,无论是迭代还是循环实现应该都不成问题),为什么有那么好的时间复杂性. 首先还是证明上述命题:注意到证明了该命题就证明了欧几里得算法的正

day 2 - 4 最大公因数 与 (扩展)欧几里得算法

一.概念引入 GCD,全名Greatest common divisor(最大公因数). 我们以gcd(a,b)表示a与b的最大公因数. 二.欧几里得算法(又名辗转相除法) 用途: 求解gcd(a,b) 核心公式: gcd(a,b) = gcd(b,a mod b)  (其中a mod b > 0) 算法思路: (保证a>b) 当a是b的倍数时,a,b最大公约数为b: *PS:此时,a mod b = 0,即gcd(a,b) = gcd(b,a mod b) = gcd(b,0) = b,可用

noip知识点总结之--欧几里得算法和扩展欧几里得算法

一.欧几里得算法 名字非常高大上的不一定难,比如欧几里得算法...其实就是求两个正整数a, b的最大公约数(即gcd),亦称辗转相除法 需要先知道一个定理: gcd(a, b) = gcd(b, a mod b) (其中a mod b != 0)  或  b (其中a mod b == 0) 证明: 后半部分呢...是废话,于是只要证明前半部分即可. 不妨设g = gcd(a, b),于是有 a = g * A, b = g * B 且 (A, B) = 1 故gcd(b, a mod b) =