方法的递归调用

目录:

  • 方法的递归调用
    • 1. 基本介绍:
    • 2. 递归能解决什么问题?
    • 3. 递归举例分析:
      • 3.1 打印问题:
      • 3.2 阶乘问题:
    • 递归的重要规则:

1. 基本介绍:

简单地说,递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题的同时让代码变得简洁,化繁为简是其核心思想。

2. 递归能解决什么问题?

  • 各种经典数学问题,如:八皇后问题汉诺塔(河内塔)阶乘问题迷宫问题青蛙跳台阶球和篮子的问题(Google编程大赛);
  • 各种算法中也会使用到递归思想,比如快速排序(quick sort),归并排序(merge sort),二分查找(binary search),分治算法(divide and conquer)等;
  • 用栈解决的问题换成递归实现 --> 递归代码比较简洁;

3. 递归举例分析:

3.1 打印问题:

我们来看一哈这一段代码:

package com.recursion;class Test{public void test(int n) {if (n > 2) {test(n - 1);}System.out.println("n=" + n);}
}public class Recursion {public static void main(String[] args) {Test t1 = new Test();t1.test(4); //尝试输出看看}
}

代码截图:

运行结果:

结果分析:
为了看起来比较规范,首先我们先简单画出 JVM内存区域 ,这里只涉及到栈空间堆空间方法区

  • 首先看到main方法(程序的入口),有C/C++基础的小伙伴们应该晓得,我们知道在调用方法时,在栈空间中会创建相应的栈帧main方法也是一个方法,也会被其他进程调用(在Linux中main函数有_start函数调用 ,这里不在展开,感兴趣的小伙伴自行了解⑧),所以自然也会形成main栈帧。此时new了一个对象,此对象会在堆中创建,在栈中的引用变量会指向此堆空间,也就是保存了此对象的地址,如图。
  • main方法中调用了test方法,所以在栈中也会创建test栈帧,此时我们传入的n为4,接下来判断n大于4吗?很明显大于4,所以在test栈中又要调用test(n-1),也就是调用test(3),既然调用了方法,那便又要在栈中创建相应的栈帧,以此类推。
  • 当调用的方法为test(2)时,此时判断n大于2显然为false,此时便要执行方法的最后一句语句,也就是sout打印语句,此时便会先打印2,打印完2之后方法结束(被操作系统回收/资源销毁),返回到前一个调用此方法的栈帧中,也是以此类推,直到main方法结束。
  • 具体机制见下图。

    接上图~~

    到这里,我们大概就能懂为啥是先打印2,再打印3,最后才打印4了。

我们再来进一步拓展一下上述问题:

源代码:

package com.recursion;class Test{public void test(int n) {if (n > 2) {test(n - 1);} else {  //唯一区别就是加了elseSystem.out.println("n=" + n);}}
}public class Recursion {public static void main(String[] args) {Test t1 = new Test();t1.test(4); //尝试输出看看}
}

代码截图:

运行结果:

尝试自己分析一下⑧,简单来说就是if执行了else就不执行,else执行了说明if也没执行。

3.2 阶乘问题:

源代码:

package com.recursion;class Test01 {public int factorial(int n) {if (n == 1) {return 1;} else {return factorial(n - 1) * n;}}
}public class Factorial {public static void main(String[] args) {Test01 test = new Test01();int ret = test.factorial(5);System.out.println("ret=" + ret);}
}

运行结果:

结果分析:
大体上都跟前面的打印例子差不多,都是调用自身时在栈上开辟相应的栈帧,前面忘说了,栈帧其实会二次开辟的,啥意思呢,就是说调用方法时先在栈上分配一块较大的空间,也就是栈帧,而在栈帧内部还会进行一次具体的内存划分,具体到每一个变量。每个栈帧结束后将返回值返回给上一个栈帧,以此类推就能清晰明了的弄清楚递归的调用机制。

递归的重要规则:

  • 执行一个方法时,就创建一个相应的新的受保护的独立空间 (栈空间/栈帧);
  • 方法的局部变量是独立的,不会相互影响,比如前面多次提到的n变量;
  • 如果方法中使用的是引用类型变量,比如数组或者String类型变量,就会共享该引用类型的数据 (指向同一堆空间);
  • 递归必须向退出递归的条件逼近,否则就是无限递归,会出现栈溢出Stack Overflow Error,也就是死循环;
  • 当一个方法执行完毕,或者遇到return时,就会返回,返回的规则遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就是执行完毕,还给操作系统,具体是啥时候还给操作系统这要看当时的环境;

【递归算法01】递归的调用机制相关推荐

  1. 递归应用场景和调用机制

    原文链接:传送门 递归 迷宫问题(回溯) 概念 简单呐的说: 递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时让代码变得简洁. 案例-递归调用机制 打印问题 p ...

  2. java同步异步调用_详解java 三种调用机制(同步、回调、异步)

    1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,jsPwwCe它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消 ...

  3. 深入浅出Java复用类【从字节码角度看toString调用机制、对象代理、组合与继承、转型、final、初始化】

    这个世界上有10种人:一种是懂二进制的,一种是不懂二进制的 你觉得类是在什么时候被加载的?[访问static域时,为什么?看完9就明白了] 文章目录 1.深入理解Java中toString方法的调用机 ...

  4. java方法调用机制_Java方法调用机制 - osc_bkdv2it5的个人空间 - OSCHINA - 中文开源技术交流社区...

    最近在编程时,修改方法传入对象的对象引用,并没有将修改反映到调用方法中.奇怪为什么结果没有变化,原因是遗忘了Java对象引用和内存分配机制.本文介绍3个点: ① 该问题举例说明 ② 简要阐述Java内 ...

  5. Netty 编解码器和 Handler 调用机制

    基本说明 1.Netty 的组件设计:Netty 的主要组件有 Channel.EventLoop.ChannelFuture.ChannelHandler.ChannelPipe 等 2.Chann ...

  6. 方法调用机制内存分析★

    方法调用机制内存分析 对于下面的程序 Persion persion = new Persion();int returnRes =persion.sum(4,6);System.out.printl ...

  7. mediasoup中nack的调用机制

    mediasoup中nack的调用机制 1 NACK作用 NACK是用来进行丢包重传的一种方式,简单的理解就是在丢包的时候会根据包序号进行重传,重传的规则可以是遇到丢包时触发,或者定时触发,这里通过m ...

  8. PHP 阿里云OpenAPI签名[RPC 调用机制]·一键登录取号[云通信号码认证服务]

    什么是RPC调用机制,我理解为 可以用 http https 访问的接口. 官方文档:RPC 调用机制 - 阿里云SDK - 阿里云https://help.aliyun.com/document_d ...

  9. OC语言基础一:OC方法调用机制,new方法实现原理

    文章目录 OC方法调用机制 new方法实现原理 野指针 内存溢出 内存泄漏 alloc和init OC方法调用机制 OC有两种方法 Person *person=[Person new]; [pers ...

最新文章

  1. 关于Android的HAL的一些理解
  2. 《C++ Primer》13.1.3节练习
  3. 深入理解InnoDB(7)—系统表空间
  4. leetcode hot100(第二部分) + python(c++)
  5. Openwrt之移动硬盘ext3/ext4格式化工具
  6. 线程范围内的线程共享(多线程)
  7. FormBorderStyle 枚举
  8. Codeforces Round #524 (Div. 2) Masha and two friends
  9. Hibernate标准查询
  10. hadoop 启动 报running beyond virtual memory错误的解决
  11. hexo(sakura)仿gitee添加文章贡献度日历图(echarts)
  12. 5G商用元年开启万亿市场, 25G服务器端口出货量大幅增长
  13. 钢琴学习:B站:时一:《万能左手伴奏》
  14. japi项目需求分析阶段
  15. 6种自动化测试框架(总有一款适合你)
  16. 超详细的WMS仓储管理系统介绍——盘点篇
  17. wps怎么转换成jpg格式?
  18. 全栈开发实战|​名片管理系统的设计与实现(SSM + JSP)
  19. Iphone开发(七)date picker 和 picker view,较复杂的控件
  20. uiq3.0sdk最终版模拟器显示中文

热门文章

  1. 华为徐直军:2020年将末位淘汰10%主管,生存是第一要务
  2. vivo X30系列发布会邀请函曝光:名副其实的“望远镜”
  3. 4岁的拼多多超越20岁的百度,成为中国第五大互联网公司!
  4. 蔚来汽车:ES6和ES8首任车主可享受终生免费换电服务
  5. 新iPhone XR全配色曝光:苹果你清醒一点 还在搞配色?
  6. 苹果要完!传iOS 13将不兼容iPhone 6、iPhone SE和iPhone 5s等机型
  7. 1799元!OPPO A9悄然上架:4月30日正式开售
  8. 拳王虚拟项目公社:2020年虚拟资源项目的最新正确玩法
  9. 构造函数后面的冒号后初始化列表
  10. Web开发之二:什么是前端、什么是后端