歐幾里得算法(輾轉相除法) 證明及復雜度分析


 

歐幾里得算法核心:

gcd( a , b ) = gcd( b , a%b ) ,其中 gcd 表示 a 和 b 的最大公約數;

證明:

設 a 和 b 的最大公約數為 c ;
則有 c = gcd( a , b ) ;
a = x * c , b = y * c , 其中 x 與 y 互質 (因為 c 是最大公約數)
g = a%b = a - i * b = (x - i * y ) * c , 其中 i = [ a / b ] ,向下取整 ;
又 b = y * c , 且易得 x - i * y 與 y 互質;(下面會證明)
則有 b 與 g 的最大公約數為 c ,
又 g = a%b,
則 gcd( a, b ) = gcd( b , a%b );

接下來,證明 x - i * y 與 y 互質 ,
反證法:
設 x - i * y 與 y 不互質;
則 x - i * y 與 y 存在最大公約數 k ( k>1 ) ;
x - i * y = n * k, y = m * k, 其中 n 和 m 互質;
把 y = m * k, 代入 x 中 得:
x = (n + i * m ) * k
又 y = m * k ,
故 x 與 y 不互質 ,與 上述證明矛盾(前面設x,y是互質的);
所以 x - i * y 與 y 互質 ;

證畢;

gcd( a , b ) = gcd( b , a%b ),求解 a、b 的最大公約數 ,化為 求解b 、a%b 的最大公約數;

符合遞歸 大問題化成小問題 求解的特性(也可以用循環求解) ;

當前遞歸到 a%b == 0時(b 整除 a), 即 下一次遞歸的 b‘ = 0;

下一次遞歸 的 a’ ,即為當前層 的 b,為最大公約數;

掛代碼

1 int gcd(int a,int b)
2 {
3     return b?gcd(b,a%b):a;
4 }

 


復雜度分析

若 a=b, 那么最大公約數就是b ;
若 a < b , 那么 經過一次操作后 gcd(a ,b) = gcd( b, a%b) = gcd( b , a );
此時, a’ = b, b’ = a % b , a’ > b’ ;

則還是來看 a > b 的情況:

  1. a < 2 * b :
    設 a = 2k (乘號省略),b = k + m (0<m<k);
    第一次操作 變為 gcd( k+m , k-m ) ; // ( a%b = a - i b )
    第二次操作 變為 gcd( k-m, r ) , r = (k+m)%(k-m) < k-m ;
    k-m < k = a/2;
    即兩次操作 數據量 最差變為原來的一半,所以復雜度為 O(2logN) ;
  2. a > 2 * b :
    設 a = 2k (乘號省略),b = k - m (0<m<k);
    第一次操作就 變為 gcd (k-m, 2k%(k-m) );
    數據量變為原來一半;
  3. a=2 * b
    最大公約數就是 max( b , 2) ;

綜上,最壞時間復雜度 約為 O(2logN) ,去掉常數即為 O(logN) , 底數為 2;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM