GCD函数递归运行时间(欧几里德算法)

GCD函数递归运行时间(欧几里德算法),c,runtime,time-complexity,recurrence,greatest-common-divisor,C,Runtime,Time Complexity,Recurrence,Greatest Common Divisor,我只能找到关于如何递归和迭代地实现gcd函数的帖子,但是我找不到这篇。我确信它在Stackoverflow上,但是我找不到它,所以如果是重复的帖子,我道歉 我看过维基百科()上的分析,无法理解它们的重复关系 考虑以下在C中递归实现的GCD函数的实现。它有一个先决条件,即两个数字都必须是正数,但与运行时无关 int gcd( int const a, int const b ) { // Checks pre conditions. assert( a >= 0 ); asse

我只能找到关于如何递归和迭代地实现gcd函数的帖子,但是我找不到这篇。我确信它在Stackoverflow上,但是我找不到它,所以如果是重复的帖子,我道歉


我看过维基百科()上的分析,无法理解它们的重复关系

考虑以下在C中递归实现的GCD函数的实现。它有一个先决条件,即两个数字都必须是正数,但与运行时无关

int gcd( int const a, int const b ) {
  // Checks pre conditions.
  assert( a >= 0 );
  assert( b >= 0 );

  if ( a < b ) return gcd( b, a );

  if ( b == 0 ) return a;

  return gcd( b, a % b );
}
int-gcd(int-const a,int-const b){
//检查前提条件。
断言(a>=0);
断言(b>=0);
如果(a

通过对运行时进行分析,我发现每个操作都是O(1),因此我们知道目前为止的递归关系是:T(n)=O(1)+???。现在要分析递归调用,我不确定如何将a(mod b)解释为我的递归调用,以正确地说明我的递归关系。

在每个递归步骤,
gcd
将把一个参数减半(最多)。要了解这一点,请看以下两种情况:

如果
b>=a/2
,那么在下一步中,您将有
a'=b
b'
,因为
%
操作将从
a
中删除
b
或更多

如果
b
,那么在下一步中,您将得到
a'=b
b'
,因为
%
操作最多只能返回
b-1


因此,在每个递归步骤中,
gcd
将把一个参数减半(最多)。这是O(log(N))步,其中N是初始
a
b
的最大值。要分析欧几里得GCD,应该使用斐波那契对:GCD(Fib[N],Fib[N-1])-最坏情况

如果您在上面测试您的欧几里德GCD,您将得到24个递归调用

如果您习惯于递归关系求解,以下内容可能会让您感兴趣:

通过这项研究,我们无法推断出任何除数/除数对的精确迭代次数(因此使用小Oh符号),但它保证了这个上界是有效的。
通常,下限为ω(1)(例如,当除数为1时)。

一个简单的分析和证明如下:

  • 显示如果
    Euclid(a,b)
    需要的步骤超过
    N
    步数,则
    a>=F(n+1)
    b>=F(n)
    ,其中
    F(i)
    i
    th斐波那契 号码
    这可以通过归纳法轻松完成

  • 显示
    F(n)
    &geq;φn-1,同样由 归纳法

  • 利用第1步和第2步的结果,我们得到了b&geq<代码>F(n)&geq; φn-1
    两边取对数, 对数φb&geq;n-1

    因此证明,n&leq;1 + 对数φb


  • 这个界限可以改进。
    EUCLID(ka,kb)
    中的递归调用数与
    EUCLID(a,b)
    中的递归调用数相同,其中
    k
    是某个整数。

    因此,边界被改进为1+logφ(b/gcd(a,b))