这个算法可以用来求解两个非负整数 a,ba,b 的最大公因数 \gcd\left({a,b}\right)gcd(a,b)。算法的步骤如下:
这个算法用自己定义了自己,也就是 递归 的。
这个算法的最早出现在《原本》(欧几里得著)中,用于求解两条线段的“最大共度”,因此也叫做“欧几里德算法”。这个算法也出现在《九章算术》中,叫做“更相减损术”。从细节上看,“更相减损术”有一个预判两个数是否都是偶数的过程,不过“更相减损”的过程和这个算法是一致的。证明辗转相除法可以停下,我们构造一个辅助函数
f\left({a,b}\right)=a+2bf(a,b)=a+2b。对于非负整数 a,ba,b,f\left({a,b}\right)f(a,b) 也是一个非负整数。
下面我们用所谓的 递降法 证明算法将会停下。
如果算法选择了步骤 1(b=0b=0),则算法已经停止;否则,算法将选择步骤 2(将 a,ba,b 替换为 b,a-b\left\lfloor{\frac{a}{b}}\right\rfloorb,a−b⌊ba⌋),那么有
\begin{array}{rcl}f\left({b,a-b\left\lfloor{\frac{a}{b}}\right\rfloor}\right)-f\left({a,b}\right)&=&a-b-2b\left\lfloor{\frac{a}{b}}\right\rfloor\\\\&\leq&a-b-b\left\lfloor{\frac{a}{b}}\right\rfloor\\\\&<&a-b-b\left({\frac{a}{b}-1}\right)\ =\ 0.\end{array}f(b,a−b⌊ba⌋)−f(a,b)=≤<a−b−2b⌊ba⌋a−b−b⌊ba⌋a−b−b(ba−1) = 0.
这说明,只要算法不结束,ff 的值在严格下降,但是起初 f=a+2bf=a+2b 是一个有限的数,因此不可能无限下降下去。因此,算法在某个时刻会停下。我们知道这个算法可以停下来了,那么,算法给出的数是否是正确的呢?当然是,下面我们就会证明这件事情。
命题 \forall k\in\mathbb{Z}, \gcd\left({a,b}\right)=\gcd\left({b,a-kb}\right).∀k∈Z,gcd(a,b)=gcd(b,a−kb).
证明 设 x=\gcd\left({a,b}\right)x=gcd(a,b),则 x|a, x|bx∣a,x∣b,从而 x|b, x|{a-kb}x∣b,x∣a−kb,于是我们有
\gcd\left({a,b}\right)=x\leq\gcd\left({b,a-kb}\right).gcd(a,b)=x≤gcd(b,a−kb).
同理, \gcd\left({a-kb,b}\right)\leq\gcd\left({b,a-kb-\left(-k\right)b}\right).gcd(a−kb,b)≤gcd(b,a−kb−(−k)b).
再利用 \gcdgcd 的对称性,有 \gcd\left({a-kb,b}\right)=\gcd\left({b,a-kb}\right)gcd(a−kb,b)=gcd(b,a−kb) 和 \gcd\left({b,a-kb-\left(-k\right)b}\right)=\gcd\left({a,b}\right)gcd(b,a−kb−(−k)b)=gcd(a,b),于是命题得证。
现在只要取 k=\left\lfloor{\frac{a}{b}}\right\rfloork=⌊ba⌋ 就证明了辗转相除法的 输出的正确性。
至此,我们已经完整地证明了辗转相除法的 正确性,它包括辗转相除法的 可终结性 和它的 输出的正确性。下一节,你将使用 第二归纳法 重新证明辗转相除法的 可终结性,别担心,核心思路是一样的,只是换一种叙述方式