c语言——递归算法

一、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 记录了已经计算过的结果,避免了重复计算,提高了效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值