函数递归与迭代图解

本文深入探讨了函数递归的概念,强调了递归的两个必要条件:限制条件和逐步接近限制条件。通过举例展示了如何递归打印整数的每一位和计算字符串长度。同时,对比了递归与迭代,分析了递归在计算斐波那契数列和阶乘时可能导致的栈溢出问题。提出了将递归转换为非递归以及使用static对象来优化递归函数的建议,指出迭代实现虽然可能降低代码可读性,但在效率上优于递归。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、函数递归

1. 什么是递归?

程序调用自身的编程技巧称为递归( recursion)。

递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式在于:把大事化小

2. 递归的两个必要条件

(1)存在限制条件,当满足这个限制条件的时候,递归便不再继续。

void print(unsigned int n)
{
   
	//if (n > 9) 没有条件时代码出现问题(栈溢出)
	{
   
		print(n / 10);
	}
	printf("%d ", n % 10);
}

在这里插入图片描述
在这里插入图片描述

(2)每次递归调用之后越来越接近这个限制条件。

3. 练习

💡 接受一个整型值(无符号),按照顺序打印它的每一位。
  例如:输入:1234,输出 1 2 3 4

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void print(unsigned int n)
{
   
	if (n > 9)
	{
   
		print(n / 10);
	}
	printf("%d ", n % 10);
}

int main()
{
   
	//接收一个整型值(无符号),按照顺序打印它的每一位
	unsigned int num = 0;
	scanf("%u", &num);
	print(num);
	return 0;
}

✨运行结果✨
在这里插入图片描述
🌸分析:
在这里插入图片描述
💡 编写函数,求字符串的长度。

#include<stdio.h>

int my_strlen(
<think>嗯,用户想要用JavaScript实现递归计算阶乘的代码示例。首先,我需要回忆一下阶乘的定义,阶乘n!是n乘以(n-1)!,直到n=0或1的时候返回1。递归的话,就是函数自己调用自己,直到达到基线条件。 根据用户提供的引用内容,比如引用[2][3],里面都有示例代码。例如,引用[2]中的函数factorial在n为0时返回1,否则返回n乘以factorial(n-1)。这个逻辑是正确的,但需要注意输入是否为非负整数,否则可能会有问题。不过用户可能只需要基础实现,不一定处理错误输入。 用户的问题可能已经看过一些示例,但需要更详细的解释或者不同的写法。比如,引用[4]详细解释了递归的执行过程,包括执行栈的变化。这可能对理解递归有帮助,所以回答中可以加入这部分内容,说明递归的调用过程。 另外,用户提到要使用中文回答,并且结构清晰,分步骤说明。所以应该先给出代码示例,然后逐步解释,再讨论注意事项,比如栈溢出问题,或者输入值的限制。 可能还需要比较递归迭代方法的优劣,比如递归代码简洁但可能有栈深度限制。引用[4]中的例子提到当n较大时可能栈溢出,所以可以建议使用迭代或尾递归优化,不过JavaScript的ES6虽然支持尾调用优化,但并不是所有环境都实现了,所以需要注意。 另外,用户引用的内容中有不同的写法,比如函数名为factorial或者jc,但用户可能更习惯使用英文命名,所以示例中使用factorial更合适。 最后,生成相关问题的时候,要考虑用户可能的后续问题,比如优化、栈溢出、应用场景等,这样能帮助用户深入理解。</think>### JavaScript递归实现阶乘函数 #### 1. 基础代码实现 以下是使用递归实现阶乘的标准代码: ```javascript function factorial(n) { if (n === 0 || n === 1) { // 基线条件 return 1; } return n * factorial(n - 1); // 递归调用 } console.log(factorial(5)); // 输出: 120 ``` #### 2. 关键步骤解析 - **基线条件**:当$n=0$或$n=1$时直接返回1,这是递归终止的条件[^2][^3] - **递归过程**:对于$n > 1$的情况,通过$n \times (n-1)!$持续分解问题规模 - **调用栈分析**:以$factorial(3)$为例: ``` factorial(3) → 3 * factorial(2) → 2 * factorial(1) → 1 (基线条件返回) 最终计算: 3*2*1=6 ``` #### 3. 执行过程图解 引用[^4]描述了调用栈的详细变化过程: 1. 每次递归调用生成新的执行上下文 2. 调用栈依次压入$factorial(3)→factorial(2)→factorial(1)$ 3. 基线条件触发后,栈帧依次弹出并计算结果 4. 最终返回累计乘积 #### 4. 注意事项 - **输入验证**:应确保$n$为非负整数(可通过添加`if(n < 0) throw Error`处理) - **栈溢出风险**:当$n > 10^4$时可能超过调用栈深度限制(可用迭代法优化) #### 5. 扩展实现 箭头函数表达式版本: ```javascript const factorial = n => (n === 0) ? 1 : n * factorial(n - 1); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗小小粒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值