递归函数两种方式的区别
概述
递归函数都不陌生,比如计算n的阶乘:
function f($n){if($n <= 1) return 1;return $n * f($n-1);
}
当然,有人可能会这么写:
function f($n, $result){if($n <= 1) return $result;return f($n-1, $n*$result);
}
上面两种方式看着好像没什么区别,但是在cpu眼中,可就不一样了。
分析
函数在调用的时候会开辟一块函数栈,用来保存函数的局部变量、参数、上一个栈的指针、返回值等信息,当函数调用结束后会销毁。递归函数会一直递归下去,上层的函数栈一直不会销毁,知道递归结束,全部退出。
举个栗子,当调用f(3)
的时候,对于上面的第一种情况,函数栈大概长这样(仅保留参数和返回值,忽略其他内容):
文字描述就是:
f(1)=1
f(2)=2*f(1)=2*1=2
f(3)=3*f(2)=3*2=6
f(4)=4*f(3)=4*6=24
也就是每一次调用,都会保存本次的变量n以及递归调用的返回值,这就会导致如果递归的太神,就会开辟太多的内存。
如果使用第二种写法,会有什么不同么?
套用刚才的分析,先用文字描述一下:
f(4, 1)=f(3, 4*1)=f(2, 3*4)=f(1, 2*12)=24
有没有发现区别,区别就是,前一种写法要保存一个局部变量n,而后一种写法,都写到下一个方法的参数中了。也就是说,第二种方式,可以直接返回下层方法,不需要退回去了。当然,cpu发现这种情况,会复用函数栈,也就是说,函数栈大概是这么个情况:
看着好像也没啥区别,但是!因为可以直接返回,上图的四个栈使用的都是同一个栈。
当递归返回的是递归调用,并且讲调用直接返回,没有参与运算等,就会被这样优化,复用栈。
递归函数两种方式的区别相关推荐
- vue 路由传参 params 与 query两种方式的区别(转载)
vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了: ro ...
- java两种绑定方式_Javascript绑定事件的两种方式的区别
命名函数 function check(){ //code } 匿名函数 window.onload = function(){ //先获取元素对象,再绑定事件,绑定的是匿名函数不可重用 var bt ...
- vue 路由传参 params 与 query两种方式的区别
vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了: ro ...
- 多线程实现的两种方式及其区别
继承Thread public class Demo2_Thread {public static void main(String[] args) {MyThread mt = new MyThre ...
- docker容器运行mysql持久化_docker容器实现数据持久化的两种方式及其区别
前言 这篇博文是我对docker实现数据持久化几种方式的特征进行一个总结. 在docker中,它的存储文件系统是在dockerhost上原有的xfs或ext4架设了一层文件系统:overlay2(将此 ...
- MySQL 清空表数据的两种方式和区别
在MySQL中删除数据有两种方式:truncate table 表名.delete from 表名. 它们在以下方面存在区别: 执行效率 truncate不扫描表,相当于重新创建了表,只保留了表的结构 ...
- java创建线程的两种方式及区别
本文将介绍创建线程的两种方式,示例代码在下面,复制粘贴即可 继承Thread类方式和实现Runnable接口方式 区别:由于在开发的过程中,很多的类都会用到继承的方式,如果采用继承的方式会让各个类之间 ...
- Qt创建线程两种方式的区别
使用QT创建线程有两种方式,方式A使用moveToThread,方式B是直接继承QThread.差异主要在于方式A的槽函数将会在新线程中运行,而方式B的槽函数在旧线程中运行. 结论如下: PS:旧线程 ...
- 关于利用qrcode生成二维码的两种方式的区别
首先以下内容是查找网上资料后了解的利用qrcode.js生成二维码的额两种方式,canvas(即画布)方式和table方式(原文地址http://www.helloweba.com/view-blog ...
最新文章
- ROS控制无人机offboard模式
- 四路服务器芯片组,四路服务器主板配置
- Timus 1204 Idempotents
- post install error,please remove node_moules before retry
- mysql外表内表_mysql 子查询 将最外表带入子查询内2层 的另一种解决方法
- php和mysql一键安装包_iis+php+mysql一键安装教程和安装包
- 【UVA - 10037】Bridge(过河问题,经典贪心)
- C语言宏定义取得两数的最大值和最小值
- VirtualBox在win10下安装一个国产深度os桌面系统的操作教程
- C++ I/O 流 格式控制(上)
- Android 10如何增强移动安全性
- 零基础学习java------day1------计算机基础以及java的一些简单了解
- 第四季-专题1-课程规划与学习方法
- 桌面版 Linux 为什么打不过 Windows?Linus 现身说法!
- 微信怎么接龙?手把手教你使用微信群接龙功能
- 【STM32学习】(21)STM32实现步进电机
- Building Worlds In Unreal 学习笔记——07-11 岩石树落木灌木绘制/溪水着色器/潮湿与焦散贴花/后处理
- NS2协议分析与仿真
- 网络通信之如何广播发送
- 学会了使用计算机之后作文,我学会了计算机
热门文章
- mysql索引(b+tree)小记
- iOS中的异步和多线程概况
- 清华大学 lt;现代软件工程gt; 项目小组名单
- 顶级程序员的心得ndash;Coders at Work
- android studio导入eclipse项目各种问题,eclipse项目导入android studio 各类问题及解决方法...
- android远程桌面软件毕设_向日葵远程管理软件
- Java的文件流操作
- matlab实现图片区水印,怎么在含有水印的图像中提取出水印
- yolov4 开发环境搭建_YOLOv4 的各种新实现、配置、测试、训练资源汇总
- xshell vim 不能粘贴_linux基础知识:vim(vi)的知识