一、c语言的定义
递归算法是指一个函数直接或间接地调用自身来解决问题的方法。递归通常用于解决可以分解为更小、相似子问题的问题。它包括以下三大要素:
1.明确函数的含义。
2.终止条件:它是递归结束的条件,防止无限递归调用。
3.递归调用:函数调用自身,处理更小的子问题。
二、递归与迭代的比较
递归算法:代码通常更简洁、清晰,符合人类的思维习惯,尤其是对于具有递归性质的问题。
迭代方法:代码相对复杂一些,需要手动维护循环变量和状态。
例如:阶乘计算
迭代方法代码实现:
#include <stdio.h>
// 使用迭代方法计算阶乘
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
int main() {
int num = 5; // 这里以计算5的阶乘为例
int result = factorial(num);
printf("%d 的阶乘是 %d\n", num, result);
return 0;
}
递归方法:
n!=n(n-1)!=n(n-1)(n-2)!=n(n-1)(n-2)(n-3)!=...=n(n-1)(n-2)(n-3)(n-4)...3*2*1
f(n)=n!
f(n)=nf(n-1)=n(n-1)f(n-2)=...=n(n-1)(n-2)(n-3)...3*2*f(1)
#include <stdio.h>
// 计算n的阶乘的递归函数
int factorial(int n) {
// 基线条件
if (n == 0 || n == 1) {
return 1;
}
// 递归调用
return n * factorial(n - 1);
}
在上述代码中,factorial函数计算一个数的阶乘。当n为0或者1时,函数返回1为终止条件。否则,它返回n乘以n-1的阶乘,这是通过递归调用factorial(n-1)实现的。
三、递归的应用
1.斐波那契数列
F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>1)
代码实现:
#include <stdio.h>
// 递归函数计算斐波那契数列
int fibonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
int main() {
int n = 10;
int result = fibonacci(n);
printf("第 %d 个斐波那契数是: %d\n", n, result);
return 0;
}
在上述代码中,fibonacci函数是实现递归计算的核心部分。它先通过判断n的值是否为0或1来确定递归的终止条件,当n为0时返回0,为1时返回1。当n大于1时,通过递归调用fibonacci(n - 1)和fibonacci(n - 2)并将结果相加,从而得到第n个斐波那契数。
2.gcd问题
GCD即最大公约数(Greatest Common Divisor),指两个或多个整数共有约数中最大的一个。计算两个数的最大公约数常见的方法有欧几里得算法(辗转相除法)
#include <stdio.h>
// 递归函数求最大公约数
int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
int main() {
int num1 = 24;
int num2 = 18;
int result = gcd(num1, num2);
printf(" %d 和 %d 的最大公约数是 %d\n", num1, num2, result);
return 0;
}
在上述代码中,gcd 函数不断调用自身,通过辗转相除的方式逐步缩小问题规模,直到 b 为 0 时返回 a 即为最大公约数。
3.爬楼梯问题
题目为:假设你正在爬楼梯,需要爬到n阶你才能到达楼顶。每次你可以爬1阶或者两阶。有多少种不同的方法可以爬到楼顶?
这里可以设f(n)为爬到n阶的方法有多少种。
#include <stdio.h>
// 递归函数计算爬楼梯的方法数
int climbStairs(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
int main() {
int n = 5; // 这里以5阶楼梯为例
int result = climbStairs(n);
printf("爬 %d 阶楼梯有 %d 种不同的方法\n", n, result);
return 0;
}
四、优化递归算法
在上述爬楼梯问题中,运用动态规划方法可以使效率更高,避免递归中的重复计算。
代码如下:
#include <stdio.h>
// 动态规划函数计算爬楼梯的方法数
int climbStairsDP(int n) {
if (n == 1) {
return 1;
}
int dp[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
int main() {
int n = 5; // 这里以5阶楼梯为例
int result = climbStairsDP(n);
printf("爬 %d 阶楼梯有 %d 种不同的方法\n", n, result);
return 0;
}
在递归方法中,climbStairs 函数会不断调用自身来计算不同阶数的方法数,当 n 较大时会有很多重复计算,效率较低。而动态规划方法 climbStairsDP 则通过数组 dp 记录了已经计算过的结果,避免了重复计算,提高了效率。