递归和迭代

c通过运行时堆栈支持递归函数的实现

递归函数就是直接或间接的调用自身的函数。
许多的书上在讲解递归的时候都会用阶乘和斐波那契数列来举例子但是非常不幸的是这两个栗子中,第一个栗子中递归并没有提供任何优越之处,而第二个栗子它的效率之低是肥肠恐怖的!!

我们在之前会学到函数在调用的时候会压栈,调用一次压一次,所以使用递归函数的时候函调用很多很多次堆栈!!这个耗费是肥肠肥肠大的!!那效率是真的很低!!!

我们可以来看一个简单的栗子

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void Print(int i)
{
    int num = i / 10;//将i/10进入递归函数
    if (num != 0)
    {
        Print(num);//进入函数
    }
    printf("%d  ", i % 10 );
    return;
}
int main()
{
    int i=4267;
    Print(i);
    system("pause");
    return 0;
}

函数一个一个的压栈,因为栈是一种先进先出的规则,所以最后一个压栈的函数最先释放!!所以它会最先打出来!我们可以画个图看一看

这里写图片描述
很明显我们可以看到函数的一个压栈的过程,在最后一次函数调用的的过程中num已经变成0,已经不符合if条件所以递归停止,执行后面的语句

printf("%d",i%10);

输出i除10的余数,那么第一个就是4,之后是2······依次打印
但我们在使用递归的时候我们一定要有一个递归的终止条件否则就会出现栈溢出的情况!!这个肥肠重要!!

其实有趣的是,c语言标准中并未说到递归需要堆栈,但是堆栈是非常适合实现递归的所以很多编译器都是用堆栈来实现递归

我们再来看一个栗子,关于我们的斐波那契数列!!我们用这个栗子来说明递归和迭代的一个效率问题
首先我们先用递归来实现斐波那契数列,并且在函数中使用clock函数来计算一下函数的执行的时间,我们就能很明显的比较出它和迭代的效率问题。

我们先来看主函数

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
int main()
{
    clock_t clock1 = clock() / CLOCKS_PER_SEC;
    int i;
    printf("请输入数字:(求第几个斐波那契数)");
    scanf("%d", &i);
    size_t add = FeiBo(i);
    clock_t clock2 = clock() / CLOCKS_PER_SEC;
    printf("数字是:");
    printf("%lu\n", add);
    printf("运行时间为(以秒为单位):");
    printf("%lu\n", clock2 - clock1);
    system("pause");
    return 0;
}

在主函数中我是用了一个计时函数(clock),因为这个时钟函数返回的只是一个近似值,所以我就在main函数刚开始的时候调用一次,在函数快结束的时候在调用一次,然后两个值相减就可以比较准确的得到该函数的一个准确的运行时间,方便我们进行比较。
这个clock函数我就不再多说感兴趣的乐意查一下度娘,很简单的

递归

size_t FeiBo(int num)
{
    if (num <= 2)
    {
        return 1;
    }
    else
    {
        return FeiBo(num - 1) + FeiBo(num - 2);
    }
}

运行结果
这里写图片描述

迭代

size_t  FeiBo(int num)
{
    size_t i = 0;
    size_t j = 1;
    size_t add = 1;
    while (num > 2)
    {
        num = num - 1;
        i = j;
        j = add;
        add = i + j;
    }
    return add;
}

运行结果
这里写图片描述
我们乐意很明显的通过clock函数看出来函数的一个运行时间,一个是13秒,一个是2秒,所以迭代的效率真的是比递归高的真的不是一星半点!!
所以我们在使用递归的时候一定要先问问自己,使用递归的好处是否能低的上使用它的代价,而且必须小心,这个代价可能比你初看上去大很多!!

好啦!!!要是有什么不对的地方!^-^一定要说出来哦!!感谢你!!

<think>好的,用户想了解递归迭代的概念及使用场景,需要详细的解释对比。首先,我需要回忆一下递归迭代的基本定义,然后整理它们的区别、优缺点以及适用场景。 根据引用[2],递归是程序调用自身,把大问题分解成小问题,这样减少代码量,但需要边界条件。而迭代则是重复执行某段代码,通常用循环结构,像for、while这些。引用[3]提到递归的例子有斐波那契数列、阶乘、汉诺塔等,而迭代可能更常见于需要逐步接近解的情况,比如数值分析中的迭代方法。 接下来,区别方面,引用[4]指出递归函数代码不会复制,每一级的变量独立,但调用可能很深,导致溢出。迭代则没有这个问题,但代码可能更长。性能方面,递归可能效率低,因为函数调用开销大,而迭代通常更快,但有时候递归的代码更简洁易读。 优缺点部分,递归的优点是代码简洁,适合解决分治、树结构等问题,缺点是溢出风险效率问题。迭代的优点是效率高,控制灵活,适合线性处理,缺点是实现复杂问题时代码可能冗长。 使用场景的话,递归适合问题可分解为相似子问题的情况,比如遍历树、排序算法中的快速排序归并排序。迭代适合循环次数明确或需要高效执行的情况,比如计算阶乘的循环实现、图像处理中的像素遍历。 还需要对比它们的实现方式,递归函数自我调用,依赖结构,而迭代用循环结构,手动维护状态。比如斐波那契数列,递归实现简单但效率低,迭代实现则更快。 可能用户还想知道如何选择两者,比如在性能要求高时选迭代,问题结构适合递归时选递归。同时,引用[5]提到迭代在开发过程中可以逐步改进,类似于敏捷开发,这可能帮助用户理解迭代在实际中的应用。 最后,确保回答结构清晰,分点解释,给出例子,并总结对比表格,方便用户理解。还要注意用户可能有的后续问题,比如如何转换递归迭代,或者具体算法中的应用,所以在相关问题里可以提出来。</think>### 递归迭代的详细解释及对比 #### 一、基本概念 1. **递归(Recursion)** 通过函数调用自身解决问题,将复杂问题分解为相似的小规模子问题[^2]。例如,计算阶乘 $n! = n \times (n-1)!$ 时,可通过递归实现: ```python def factorial(n): if n == 0: return 1 return n * factorial(n-1) ``` 2. **迭代(Iteration)** 通过循环结构重复执行代码逐步逼近解。例如,用循环计算阶乘: ```python def factorial_iter(n): result = 1 for i in range(1, n+1): result *= i return result ``` --- #### 二、核心区别 | **特性** | **递归** | **迭代** | |----------------|------------------------------------------|--------------------------------| | **实现方式** | 函数自我调用,依赖系统调用 | 循环结构(`for`/`while`) | | **代码复杂度** | 代码简洁,逻辑清晰 | 需手动维护状态变量,代码可能冗长 | | **性能** | 函数调用开销大,可能溢出[^4] | 效率高,无额外内存消耗 | | **适用场景** | 问题可分解为相似子问题(如树遍历、分治) | 线性操作或循环次数明确(如遍历数组)| --- #### 三、优缺点对比 1. **递归** - **优点**:逻辑简洁,适合分治、回溯等场景(如快速排序、汉诺塔问题)[^3]。 - **缺点**:溢出风险,调试困难,重复计算可能导致低效(如斐波那契数列递归解法)[^4]。 2. **迭代** - **优点**:性能高效,内存可控(如计算大规模数列时优先选择迭代)[^5]。 - **缺点**:代码可能复杂(例如实现树的层次遍历需借助队列)。 --- #### 四、使用场景 1. **递归适用场景** - 树/图的遍历(如二叉树前序遍历) - 分治算法(如归并排序、快速排序) - 动态规划问题(如背包问题,但需结合记忆化优化) 2. **迭代适用场景** - 数组/链表遍历 - 数值计算(如牛顿迭代法解方程) - 状态机处理(如游戏循环、实时系统) --- #### 五、典型示例 1. **斐波那契数列** - 递归实现(低效但直观): $$F(n) = F(n-1) + F(n-2) \quad \text{(边界条件:} F(0)=0, F(1)=1\text{)}$$ - 迭代实现(高效): ```python def fibonacci(n): a, b = 0, 1 for _ in range(n): a, b = b, a + b return a ``` 2. **汉诺塔问题** 递归解法体现分治思想: ```python def hanoi(n, source, target, auxiliary): if n > 0: hanoi(n-1, source, auxiliary, target) print(f"Move disk {n} from {source} to {target}") hanoi(n-1, auxiliary, target, source) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值