当前位置: 首页 > news >正文

辗转相除法(欧几里得算法)深度解析

辗转相除法-欧几里得算法深度解析

  • 前言
  • 一、辗转相除法的数学原理
    • 1.1 最大公约数(GCD)
    • 1.2 核心数学定理:带余除法
    • 1.3 算法核心步骤
  • 二、算法实现:递归与迭代
    • 2.1 cpp递归实现
    • 2.2 Python迭代实现
    • 2.3 处理负数与 0 的边界情况
  • 三、复杂度分析:对数级效率
    • 3.1 时间复杂度
    • 3.2 空间复杂度
  • 四、扩展:从辗转相除法到扩展欧几里得算法
    • 4.1 扩展欧几里得算法
    • 4.2 应用场景
  • 五、与其他 GCD 算法的对比
    • 5.1 更相减损术(九章算术算法)
    • 5.2 二进制 GCD 算法
  • 六、数学&工程应用场景
    • 6.1 分数约分
    • 6.2 多项式 GCD
    • 6.3 计算机底层实现
  • 总结

前言

辗转相除法(Euclidean Algorithm)是求解两个正整数最大公约数(GCD, Greatest Common Divisor)的经典算法。它以简洁的数学原理和高效的计算过程,成为数论算法的基石之一,广泛应用于密码学、代数运算、计算机科学等领域。本文我将从数学原理、算法实现、复杂度分析、应用场景等多个维度,深入解析这一经典算法,结合代码示例与数学证明,带你全面掌握辗转相除法的核心思想。

一、辗转相除法的数学原理

1.1 最大公约数(GCD)

两个正整数 a a a b b b 的最大公约数 d d d,是同时整除 a a a b b b 的最大正整数,记作 d = gcd ⁡ ( a , b ) d = \gcd(a, b) d=gcd(a,b)。例如:

  • gcd ⁡ ( 24 , 18 ) = 6 \gcd(24, 18) = 6 gcd(24,18)=6
  • gcd ⁡ ( 45 , 15 ) = 15 \gcd(45, 15) = 15 gcd(45,15)=15

1.2 核心数学定理:带余除法

辗转相除法基于数论中的带余除法:对于任意两个正整数 a a a b b b a > b a > b a>b),存在唯一的整数 q q q(商)和 r r r(余数),使得:

a = b ⋅ q + r ( 0 ≤ r < b ) a = b \cdot q + r \quad (0 \leq r < b) a=bq+r(0r<b)

此时, gcd ⁡ ( a , b ) = gcd ⁡ ( b , r ) \gcd(a, b) = \gcd(b, r) gcd(a,b)=gcd(b,r)证明:设 d d d a a a b b b 的公约数,则 d d d 整除 a − b ⋅ q = r a - b \cdot q = r abq=r,因此 d d d 也是 b b b r r r 的公约数。反之,若 d d d b b b r r r 的公约数,则 d d d 整除 b ⋅ q + r = a b \cdot q + r = a bq+r=a,因此 d d d 也是 a a a b b b 的公约数。故两者的公约数集合相同,最大公约数必然相等。

1.3 算法核心步骤

辗转相除法通过不断应用带余除法,将原问题转化为更小规模的子问题,直到余数为 0 时停止:

  1. 用较大数除以较小数,得到余数 r r r
  2. r = 0 r = 0 r=0,则较小数即为最大公约数。
  3. 否则,将较小数作为新的较大数,余数作为新的较小数,重复步骤 1。

示例:计算

  • 252 A ~ ⋅ 105 = 2 252 ÷ 105 = 2 252A~105=2 42 42 42 gcd ⁡ ( 252 , 105 ) = gcd ⁡ ( 105 , 42 ) \gcd(252, 105) = \gcd(105, 42) gcd(252,105)=gcd(105,42)
  • 105 A ~ ⋅ 42 = 2 105 ÷ 42 = 2 105A~42=2 21 21 21 gcd ⁡ ( 105 , 42 ) = gcd ⁡ ( 42 , 21 ) \gcd(105, 42) = \gcd(42, 21) gcd(105,42)=gcd(42,21)
  • 42 A ~ ⋅ 21 = 2 42 ÷ 21 = 2 42A~21=2 0 0 0 gcd ⁡ ( 42 , 21 ) = 21 \gcd(42, 21) = 21 gcd(42,21)=21最终结果为 21 21 21
    辗转相除法

二、算法实现:递归与迭代

2.1 cpp递归实现

#include <iostream>
using namespace std;int gcd(int a, int b) {if (b == 0) return a;return gcd(b, a % b);
}int main() {cout << gcd(252, 105) << endl; // 输出21return 0;
}

递归逻辑

  • 终止条件:当 b = 0 b = 0 b=0 时,返回 a a a(此时 a a a 是上一步的除数,即当前最大公约数)。

  • 递归调用:将问题转化为 gcd ⁡ ( b , a % b ) \gcd(b, a \% b) gcd(b,a%b),其中 a % b a \% b a%b 是上一步的余数。

2.2 Python迭代实现

def gcd(a, b):while b != 0:a, b = b, a % breturn aprint(gcd(252, 105))  # 输出21

迭代逻辑

  • 用循环替代递归,通过不断更新 a a a b b b 的值( a a a 变为原 b b b b b b 变为原 a % b a \% b a%b),直到 b = 0 b = 0 b=0 时返回 a a a

2.3 处理负数与 0 的边界情况

实际应用中需处理非正整数输入:

def gcd(a, b):a = abs(a)b = abs(b)while b != 0:a, b = b, a % breturn a
  • 先取绝对值,确保输入为正整数。

  • 若输入包含 0(如 gcd ⁡ ( 0 , 5 ) = 5 \gcd(0, 5) = 5 gcd(0,5)=5),算法依然成立,因为 gcd ⁡ ( 0 , n ) = n \gcd(0, n) = n gcd(0,n)=n n > 0 n > 0 n>0)。

三、复杂度分析:对数级效率

3.1 时间复杂度

辗转相除法的时间复杂度为 O ( log ⁡ min ⁡ ( a , b ) ) O(\log \min(a, b)) O(logmin(a,b)),证明基于以下两点:

  1. 余数递减性质:每次迭代后,余数 r = a % b r = a \% b r=a%b 满足 r < b r < b r<b,且当 a > b a > b a>b 时, a % b ≤ a / 2 a \% b \leq a/2 a%ba/2(当 a < 2 b a < 2b a<2b 时,余数 a − b < b a - b < b ab<b;当 a ≥ 2 b a \geq 2b a2b 时,余数 a % b ≤ a / 2 a \% b \leq a/2 a%ba/2)。

  2. 斐波那契数列下界:算法的迭代次数不超过较小数的位数。设 a > b a > b a>b,迭代次数为 k k k,则 a ≥ F ( k + 2 ) a \geq F(k+2) aF(k+2) b ≥ F ( k + 1 ) b \geq F(k+1) bF(k+1),其中 F ( n ) F(n) F(n) 是斐波那契数列。由于斐波那契数列呈指数增长,迭代次数 k = O ( log ⁡ b ) k = O(\log b) k=O(logb)

3.2 空间复杂度

  • 递归实现:空间复杂度为 O ( log ⁡ b ) O(\log b) O(logb)(递归栈深度)。

  • 迭代实现:空间复杂度为 O ( 1 ) O(1) O(1)(仅使用常数级变量)。

四、扩展:从辗转相除法到扩展欧几里得算法

4.1 扩展欧几里得算法

辗转相除法的扩展版本可求解贝祖等式 a x + b y = gcd ⁡ ( a , b ) ax + by = \gcd(a, b) ax+by=gcd(a,b) 的整数解 ( x , y ) (x, y) (x,y)算法思想:在求 gcd ⁡ ( a , b ) \gcd(a, b) gcd(a,b) 的过程中,反向推导 x x x y y y 的值。递归实现(Python)

def extended_gcd(a, b):if b == 0:return a, 1, 0gcd, x1, y1 = extended_gcd(b, a % b)x = y1y = x1 - (a // b) * y1return gcd, x, ygcd, x, y = extended_gcd(252, 105)
print(f"gcd={gcd}, x={x}, y={y}")
# 输出 gcd=21, x=-1, y=2(252*(-1) + 105*2 = 21)

4.2 应用场景

  • 求解线性同余方程:如 a x ≡ c m o d m ax \equiv c \mod m axcmodm,需先判断 gcd ⁡ ( a , m ) \gcd(a, m) gcd(a,m) 是否整除 c c c

  • 密码学:RSA 算法中用于计算模逆元(若 a a a m m m 互质,存在唯一的 x x x 使得 a x ≡ 1 m o d m ax \equiv 1 \mod m ax1modm)。

五、与其他 GCD 算法的对比

5.1 更相减损术(九章算术算法)

  • 原理:通过反复做差代替取余: gcd ⁡ ( a , b ) = gcd ⁡ ( ∣ a − b ∣ , b ) \gcd(a, b) = \gcd(|a-b|, b) gcd(a,b)=gcd(ab,b) a > b a > b a>b)。

  • 示例 gcd ⁡ ( 252 , 105 ) = gcd ⁡ ( 147 , 105 ) = gcd ⁡ ( 42 , 105 ) = gcd ⁡ ( 42 , 63 ) = gcd ⁡ ( 42 , 21 ) = 21 \gcd(252, 105) = \gcd(147, 105) = \gcd(42, 105) = \gcd(42, 63) = \gcd(42, 21) = 21 gcd(252,105)=gcd(147,105)=gcd(42,105)=gcd(42,63)=gcd(42,21)=21

  • 优缺点:避免取余运算(适合大数),但最坏情况时间复杂度为 O ( a + b ) O(a + b) O(a+b)(如 gcd ⁡ ( n , 1 ) \gcd(n, 1) gcd(n,1) 需要 n − 1 n-1 n1 次减法),效率低于辗转相除法。

5.2 二进制 GCD 算法

  • 原理:结合移位运算和减法,适用于二进制系统:
  1. a a a b b b 均为偶数, gcd ⁡ ( a , b ) = 2 ⋅ gcd ⁡ ( a / 2 , b / 2 ) \gcd(a, b) = 2 \cdot \gcd(a/2, b/2) gcd(a,b)=2gcd(a/2,b/2)

  2. a a a 为偶数、 b b b 为奇数, gcd ⁡ ( a , b ) = gcd ⁡ ( a / 2 , b ) \gcd(a, b) = \gcd(a/2, b) gcd(a,b)=gcd(a/2,b)

  3. a a a b b b 均为奇数, gcd ⁡ ( a , b ) = gcd ⁡ ( ∣ a − b ∣ , b ) \gcd(a, b) = \gcd(|a-b|, b) gcd(a,b)=gcd(ab,b)

  • 优点:避免大数取余,适合计算机底层实现(如 Python 的math.gcd内部优化)。

六、数学&工程应用场景

6.1 分数约分

将分数 a b \frac{a}{b} ba 约分为最简形式:

def reduce_fraction(a, b):g = gcd(a, b)return (a // g, b // g)print(reduce_fraction(18, 24))  # 输出 (3, 4)

6.2 多项式 GCD

在符号计算中,辗转相除法可扩展到多项式环,用于求解两个多项式的最大公因式,步骤与整数 GCD 类似,将取余运算替换为多项式除法。

6.3 计算机底层实现

  • 编程语言内置函数:Python 的math.gcd、C++ 的<algorithm>库中的__gcd均基于优化的辗转相除法。

  • 加密算法:RSA 算法中,通过扩展欧几里得算法计算私钥,确保加密和解密的正确性。

总结

辗转相除法以简洁的数学原理和高效的计算过程,成为数论算法的典范。它不仅解决了最大公约数的求解问题,还衍生出扩展算法,在密码学、代数运算等领域发挥关键作用。理解辗转相除法,不仅是掌握一个算法,更是理解 “问题简化” 和 “数学归纳” 思想的重要实践。

That’s all, thanks for reading!
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

http://www.xdnf.cn/news/564121.html

相关文章:

  • 内存屏障指令
  • 基于JDBC的信息管理系统,那么什么是JDBC呢?
  • VUE3+TS实现图片缩放移动弹窗
  • 10.18 LangChain ToolMessage实战:多轮交互与状态管理全解析
  • Java 项目管理工具:Maven 与 Gradle 的深度对比与选择
  • 定时器的两种实现方式
  • C语言---结构体 、联合体、枚举
  • JavaScript性能优化实战(14):跨端JavaScript性能优化
  • ​C++性能优化的7大核心策略与实战案例
  • qt浏览文件支持惯性
  • AI赋能R-Meta分析核心技术:从热点挖掘到高级模型
  • 【音频】wav文件如何解析编码格式(压缩格式)?
  • 前端开发遇到 Bug,怎么办?如何利用 AI 高效解决问题
  • 电脑中所有word文件图标变白怎么恢复
  • WebSocket 是什么?
  • SQL 数值计算全解析:ABS、CEIL、FLOOR与ROUND函数深度精讲
  • 深入了解redis的哈希槽的知识
  • 关于收集 Android Telephony 网络信息的设计思考
  • 网络基础的介绍
  • 如何提高独立服务器的安全性?
  • 从电商角度设计大模型的 Prompt
  • Java 参数值传递机制
  • 全平台开源电子书阅读器推荐,支持多端同步+AI朗读!支持epub/mobi/azw3/pdf常见电子书格式!
  • PostgreSQL基础操作
  • 29.第二阶段x64游戏实战-技能冷却
  • Node.js 24发布:性能与安全双提升
  • 【Vue篇】重剑无锋:面经PC项目工程化实战面经全解
  • 苹果企业签名为什么会出现授信异常
  • 《从虚拟 DOM 到 Diff 算法:深度解析前端高效更新的核心原理》-简版
  • logits是啥、傅里叶变换