求最大公约数(用递归的形式)

 1.辗转相除法

int gcd_1(int a, int b){
    return b == 0 ? a:gcd_1(b, a%b);
}

2. 辗转相减法

int gcd_2(int a, int b){
    return a == b ? a:gcd_2(a>b ? a-b:a, b>a ? b-a:b);
}

<think> 我们参考上述引用中的代码,总结递归和非递归最大公约数的方法。 最大公约数(Greatest Common Divisor, GCD)常用的算法是欧几里得算法(辗转相除法)。 递归方法:基于等式 gcd(a, b) = gcd(b, a mod b) 以及递归终止条件:当余数为0时,返回除数。 非递归方法:循环地进行取模运算,更新被除数和除数,直到余数为0,此时的除数就是最大公约数。 另外,引用[4]提供了一种不同的非递归方法(枚举法),即从两个数中较小的数开始递减,直到找到能同时整除两个数的数。但效率较低,我们通常使用辗转相除法。 根据用户需,我们给出递归和非递归的C语言代码实现(主要参考引用[2]和[3]): 递归函数: long gcd_recursive(int a, int b) { if (b == 0) return a; return gcd_recursive(b, a % b); } 注意:为了避免在a<b时需要多次递归交换,可以在函数开始确保a>=b,或者如引用[2]中在递归函数中处理大小关系。但我们常见的写法是先取模,因为当a<b时,a%b等于a,下一次递归就会变成gcd(b, a)(即自动交换)。所以上述代码可以处理所有情况。 非递归函数(辗转相除法): long gcd_non_recursive(int a, int b) { int temp; while (b != 0) { temp = a % b; a = b; b = temp; } return a; } 注意:非递归方法中,我们使用循环,每次计算a除以b的余数,然后将b赋值给a,余数赋值给b,直到b为0,此时a即为最大公约数。 然而,引用[1]中的非递归函数实际上是递归形式的(它内部调用了自己),并且代码有误(没有返回递归调用结果,且没有处理非递归循环)。引用[2]中的非递归函数使用do-while循环,是正确的方法。引用[3]的非递归函数使用while循环,也是正确的。 现在,我们按照引用[2]和[3]中的正确实现,给出一个完整的程序: 注意:为了兼容性,我们避免使用<conio.h>和getch(),使用标准输入输出。 完整代码示例: */ </think> 以下是C语言实现递归和非递归形式最大公约数(GCD)的代码,基于欧几里得算法(辗转相除法): ### 1. 递归实现 ```c #include <stdio.h> int gcd_recursive(int a, int b) { if (b == 0) // 递归终止条件 return a; return gcd_recursive(b, a % b); // 递归调用 } int main() { int num1 = 48, num2 = 18; printf("GCD(%d, %d) = %d\n", num1, num2, gcd_recursive(num1, num2)); return 0; } ``` **原理**:$gcd(a, b) = gcd(b, a \mod b)$,当余数为0时返回除数[^2][^3]。 ### 2. 非递归实现 ```c #include <stdio.h> int gcd_non_recursive(int a, int b) { int temp; while (b != 0) { // 循环直到余数为0 temp = a % b; // 计算余数 a = b; // 更新被除数 b = temp; // 更新除数 } return a; } int main() { int num1 = 56, num2 = 32; printf("GCD(%d, %d) = %d\n", num1, num2, gcd_non_recursive(num1, num2)); return 0; } ``` **原理**:通过循环不断更新被除数和除数,直到余数为0,此时除数即为GCD[^2][^3]。 ### 关键点说明 1. **时间复杂度**:两种方法均为 $O(\log(\min(a, b)))$ 2. **参数处理**: - 当 $a < b$ 时,第一轮迭代会交换两数位置(如递归中首次计算 $a \mod b = a$,非递归中 $temp = a$) - 处理负数需先取绝对值 3. **特殊输入**: - 若 $b=0$,直接返回 $|a|$ - 若两数均为0,结果未定义(数学上GCD(0,0)无意义) ### 算法对比 | 特性 | 递归方法 | 非递归方法 | |--------------|------------------------------|----------------------------| | **空间复杂度** | $O(\log n)$ (调用栈) | $O(1)$ (常数空间) | | **适用场景** | 代码简洁,小规模数据 | 大数据量,避免栈溢出风险 | | **效率** | 函数调用开销大 | 直接循环效率更高 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值