1. 程式人生 > >歐幾里得演算法時間複雜度簡單分析

歐幾里得演算法時間複雜度簡單分析

前言

這個問題是在《資料結構與演算法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))。

最後一步的推理顯得不是那麼嚴謹,但大體的規律能夠表現出來。其實對於這種最壞的情況,拉梅定理就給出了步數的計算公式。

總結

拉梅定理的證明在給出的連結中已經詳細的給出,有興趣的朋友可以看看!相信隨著學習演算法的逐漸深入,會發現數學在科學的領域裡總是有用武之地的!它們兩個還真是“愛恨糾纏不休”啊!