欧几里得算法时间复杂度简单分析

前言
这个问题是在《数据结构与算法C++描述(第三版中文)》所遇到的,文中给出的迭代次数O(logN)的结果就像是教授所说的“显然”一样高深莫测,有点云里雾里的感觉!在“网罗”了一些资料后,在这里找到了自己想要的答案,笔者接下来就结合自己的理解列出文章中的求解过程。
数学是科学的“皇后”
在前言中提到那本书中也明确指出了欧几里得算法在实现过程理解上可能不是很难,但是想要得出其在平均情况下的性能需要大量的高度复杂的数学运算分析,书中给出了一个最终的迭代平均次数结果:
次数n = (12 * ln2 * lnN) / π ^ 2 + 1.47 (N为其中较小的那个数)
所以后面就只是考虑一个最坏的情况:M、N(M > N)是两个相邻的斐波那契数,程序是这样的(来源于该书):
long gcd( long m, long n) { while(n != 0) { long rem = m %n; m = n; n = rem }return m; }

  1. 假设M ≥ N ≥ 1(如果M < N,在第一次循环后,它们就会相互交换);
  2. 定义一个数列{Remn}: Rem0 = M,Rem1 = N,Remn = Remn - 2 mod Remn - 1(n >= 2);
  3. 如果算法需要进行n次迭代,则有Remn = gcd(M, N),Remn + 1 = 0;
  4. 将数列{Remn}对比于斐波那契数列{Fbn}:Fb0 = 0 ≤ Remn,Fb1 = 1 ≤ Remn - 1;
  5. 由Remk mod Remk + 1 = Remk + 2 => Remk ≥ Remk + 1 + Remk + 2;
  6. 由数学归纳法可证明:Remk ≥ Fbn - k;
  7. 故:Rem1 = N ≥ Fbn - 1,表明如果需要做n次模运算,N必定不小于Fbn - 1;
  8. 由斐波那契数列通项公式(图片来源于这里,关于第一项为0还是1没有严格的限定):
欧几里得算法时间复杂度简单分析
文章图片

可得N ≥ 1 / √5(((1 + √5) / 2) ^ (n - 1) - ((1- √5) / 2) ^ (n - 1)) => 次数n = O(log(N))。
最后一步的推理显得不是那么严谨,但大体的规律能够表现出来。其实对于这种最坏的情况,拉梅定理就给出了步数的计算公式。
总结
【欧几里得算法时间复杂度简单分析】拉梅定理的证明在给出的链接中已经详细的给出,有兴趣的朋友可以看看!相信随着学习算法的逐渐深入,会发现数学在科学的领域里总是有用武之地的!它们两个还真是“爱恨纠缠不休”啊!

    推荐阅读