递归 | 迭代 | 栈溢出

让我用简单的例子来解释递归和迭代的区别:

  1. 递归(Recursion):
  • 函数调用自身来解决问题
  • 像是一个套娃过程,每次都把问题变小一点
  • 需要有终止条件(不然会无限调用下去)

举个计算阶乘的例子:

// 递归方式计算 5!
public int factorial(int n) {if (n == 1) {         // 终止条件return 1;}return n * factorial(n-1);  // 调用自己
}// 执行过程:
factorial(5)
= 5 * factorial(4)
= 5 * (4 * factorial(3))
= 5 * (4 * (3 * factorial(2)))
= 5 * (4 * (3 * (2 * factorial(1))))
= 5 * (4 * (3 * (2 * 1)))
= 120
  1. 迭代(Iteration):
  • 使用循环结构(for、while)来重复执行
  • 像是在平地上一步步走
  • 用变量来记录状态

同样的阶乘用迭代写:

// 迭代方式计算 5!
public int factorial(int n) {int result = 1;for(int i = 1; i <= n; i++) {result = result * i;}return result;
}// 执行过程:
result = 1
result = 1 * 1 = 1
result = 1 * 2 = 2
result = 2 * 3 = 6
result = 6 * 4 = 24
result = 24 * 5 = 120

主要区别:

  1. 思维方式

    • 递归:把大问题分解成小问题
    • 迭代:步步循环,直到完成
  2. 内存使用

    • 递归:每次调用都会占用新的栈空间
    • 迭代:只需要循环变量的空间
  3. 代码风格

    • 递归:代码通常更简洁优雅
    • 迭代:代码可能更直观易懂

回到你之前问的二叉树遍历的例子:

// 递归方式
public void preorder(TreeNode root) {if (root == null) return;System.out.print(root.val);  // 先访问根节点preorder(root.left);         // 递归访问左子树preorder(root.right);        // 递归访问右子树
}// 迭代方式
public void preorder(TreeNode root) {Stack<TreeNode> stack = new Stack<>();while (root != null || !stack.isEmpty()) {while (root != null) {System.out.print(root.val);stack.push(root);root = root.left;}root = stack.pop().right;}
}

递归在处理树、图这样的数据结构时特别有用,因为它们本身就是递归定义的。但递归也可能导致栈溢出,所以有时候需要改写成迭代形式。

让我解释一下什么是栈溢出(Stack Overflow):

栈溢出就像往一个杯子里不停倒水,最后水溢出来了一样。具体来说:

  1. 什么是栈?
// 每调用一个方法,就会在栈上分配一块内存
void methodA() {methodA();  // 递归调用自己
}
  • 栈是一块有限的内存空间
  • 每次调用方法都会占用一些栈空间
  • 方法执行完后会释放这些空间
  1. 什么情况会栈溢出?
// 容易导致栈溢出的代码
void infiniteRecursion(int n) {System.out.println(n);infiniteRecursion(n + 1);  // 没有终止条件的递归
}
  • 递归调用太深(比如上面的代码)
  • 方法调用层次太多
  • 局部变量占用空间太大
  1. 一个简单的栈溢出例子:
public static void main(String[] args) {count(1);
}public static void count(int n) {System.out.println(n);  // 打印当前数字count(n + 1);          // 一直递归,没有停止条件
}
// 运行结果:
// 1
// 2
// 3
// ...
// Exception in thread "main" java.lang.StackOverflowError
  1. 如何避免栈溢出:
// 好的写法:有终止条件
public static void count(int n) {if (n > 1000) return;  // 设置终止条件System.out.println(n);count(n + 1);
}// 或者改用循环
public static void count(int n) {while (n <= 1000) {System.out.println(n);n++;}
}
  • 设置合适的递归终止条件
  • 考虑使用循环替代递归
  • 使用尾递归优化(某些语言支持)
  • 控制递归深度

所以在写递归代码时,一定要注意设置合适的终止条件,避免无限递归导致栈溢出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux dd命令读写flash之误区

1. 问题 通常在Linux系统上需使用dd命令读写flash设备&#xff0c;个人最近调试了一款spi-nor flash芯片&#xff0c;分区分配了8MB大小的分区&#xff0c;是用dd命令验证读写flash时&#xff0c;出现校验失败。 使用如下命令读写8KB数据就会出现校验数据失败 time dd if/dev…

大数据挖掘建模平台案例分享

大数据挖掘建模平台是由泰迪自主研发&#xff0c;面向企业级用户的大数据挖掘建模平台。平台采用可视化操作方式&#xff0c;通过丰富内置算法&#xff0c;帮助用户快速、一站式地进行数据分析及挖掘建模&#xff0c;可应用于处理海量数据、高复杂性的数据挖掘任务&#xff0c;…

顺序表(数据结构初阶)

文章目录 顺序表一&#xff1a;线性表1.1概念&#xff1a; 二&#xff1a;顺序表2.1概念与结构&#xff1a;2.2分类&#xff1a;2.2.1静态顺序表2.2.2动态顺序表 2.3动态顺序表的实现声明&#xff08;初始化&#xff09;检查空间容量尾插头插尾删头删查找指定位置之前插入数据指…

Cherno C++学习笔记 P37 三元运算符

这里我们穿插讲一下C里面的三元运算符。三元运算符其实很简单&#xff0c;就是&#xff1f;与&#xff1a;两个符号的结合&#xff0c;本质上只是一个if else语法的语法糖。这个符号可以让我们根据一个条件来赋值。 我们举一个简单的例子来体现一下三元运算符的用法&#xff1…

【[LeetCode每日一题】Leetcode 1768.交替合并字符串

Leetcode 1768.交替合并字符串 题目描述&#xff1a; 给定两个字符串 word1 和 word2&#xff0c;以交替的方式将它们合并成一个新的字符串。即&#xff0c;第一个字符来自 word1&#xff0c;第二个字符来自 word2&#xff0c;第三个字符来自 word1&#xff0c;依此类推。如果…

【伪代码】数据结构-期末复习 线性表

目录 例1 矩阵相乘 线性表 2.1 线性表的类型定义 例2-1 求并集 LALA∪LB 例2-2 有序表归并 2. 2 线性表的顺序表示和实现 1&#xff0e;构造空表 2&#xff0e;插入 3&#xff0e;删除 4&#xff0e;定位 顺序表的优点&#xff1a; 顺序表的缺点&#xff1a; 例…

Linux 设备树

学习设备树之前你需要知道什么&#xff1f; 因为设备树描述了整个芯片和开发板等所有硬件信息内容&#xff0c;所以他的信息量是非常庞大的&#xff0c;RK的linux的设备树算下来大概就有九千多行&#xff0c;大家不要被这个数字给吓到&#xff0c;这些内容都是原厂工程师写的&a…

pytorch_fid 安装笔记

目录 torch安装&#xff1a; pytorch_fid安装 torch安装&#xff1a; pip install torch2.5.0 --index-url https://download.pytorch.org/whl/cu121 pytorch_fid安装 pip install pytorch_fid 安装后&#xff0c;torch也会自动安装&#xff0c;导致torch引用报错。

IoTDB 如何修改测点类型

问题 时序数据库 IoTDB 如果在数据插入时未指定属性值的类型&#xff0c;而后期需要将原本推断为 INT32 类型的数据强制转换为 TEXT 类型&#xff0c;应如何处理&#xff1f;如果字段类型不支持直接修改&#xff0c;是否有其他方案可以实现字段类型的调整&#xff1f;如何将设…

虚幻引擎内各个组件的关系

1. GameMode: 关系: GameMode 是游戏规则的制定者和管理者,GameState 则是游戏状态的记录者和同步者。GameMode 通常负责创建和初始化 GameState。 交互: GameMode 可以直接访问和修改 GameState 的属性,例如更新游戏分数、切换游戏阶段等。GameState 的变化会通过 GameMode …

力扣刷题TOP101: 32.BM39 序列化二叉树

目录&#xff1a; 目的 思路 复杂度 记忆秘诀 python代码 目的&#xff1a; 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树&#xff0c;不对序列化之后的字符串进行约束&#xff0c;但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。 思路…

MySQL有哪些高可用方案?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL有哪些高可用方案?】面试题。希望对大家有帮助&#xff1b; MySQL有哪些高可用方案? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 高可用方案旨在确保数据库系统的高可靠性、低宕机时间、以及在硬件故障…

An error happened while trying to locate the file on the Hub and we cannot f

An error happened while trying to locate the file on the Hub and we cannot find the requested files in the local cache. Please check your connection and try again or make sure your Internet connection is on. 关于上述comfy ui使用control net预处理器的报错问…

Nginx之配置防盗链(Configuring Anti-hotlinking in Nginx)

运维小白入门——Nginx配置防盗 什么是防盗链&#xff1a; 防盗链技术主要用于防止未经授权的第三方或域名访问网站的静态资源。例如&#xff0c;一个网站可能拥有独特的图片素材&#xff0c;为了防止其他网站通过直接链接图片URL的方式访问这些图片&#xff0c;网站管理员会采…

深度学习:CPU和GPU算力

一、算力 “算力”&#xff08;Computing Power&#xff09;通常是指计算机或计算系统执行计算任务的能力。它是衡量系统处理数据、运行算法以及执行计算任务效率的重要指标。根据上下文&#xff0c;算力可以在以下几种场景中具体化&#xff1a; 1. 单机算力 CPU算力&#x…

【AI日记】24.12.13 kaggle 比赛 2-3 大扫除、断舍离、自己做饭

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加&#xff1a;kaggle 比赛 Regression with an Insurance Dataset参考&#xff1a;kaggle 回归类入门比赛 House Prices - Advanced Regression Techniques内容&#xff1a;构建自己的EDA&#xff08…

【echarts】数据过多时可以左右滑动查看(可鼠标可滚动条)

1. 鼠标左右拖动 在和 series 同级的地方配置 dataZoom&#xff1a; dataZoom: [{type: inside, // inside 鼠标左右拖图表&#xff0c;滚轮缩放&#xff1b; slider 使用滑动条start: 0, // 左边的滑块位置&#xff0c;表示从 0 开始显示end: 60, // 右边的滑块位置&#xf…

pytest -s执行的路径

pytest -s执行的路径&#xff1a; 直接写pytest -s&#xff0c;表示从当前路径下开始执行全部.py的文件。 执行具体指定文件&#xff1a;pytest -s .\testXdist\test_dandu.py 下面这样执行pytest -s 会报找不到文件或没权限访问&#xff0c; 必须要加上具体文件路径pytest -s…

AP AUTOSAR网络管理——Network Management R24-11

AP AUTOSAR——Network Management 1.网络管理 网络管理(Network Management,NM)的定义: NM是自适应平台服务中的一个功能集群,主要管理每个网络节点(包括物理网络和部分网络)在正常运行模式和总线关闭睡眠模式之间的转换。NM的操作独立于所使用的通信网络绑定。直接网…

预处理器Stylus的介绍及使用,并同Less、Sass进行对比(简单介绍)

目录 一、安装与配置 安装Node.js&#xff1a; 安装Stylus&#xff1a; 配置Webpack&#xff1a; 二、编写Stylus代码 定义变量&#xff1a; 使用变量&#xff1a; 嵌套语法&#xff1a; 混合&#xff08;Mixins&#xff09;&#xff1a; 函数&#xff1a; 6.关键字参…