在数据结构算法设计中,或者一个方法的具体实现的时候,有一种方法叫做“递归”,这种方法在思想上并不是特别难,但是实现起来还是有一些需要注意的。虽然对于很多递归算法都可以由相应的循环迭代来代替,但是对于一些比较抽象复杂的算法不用递归很难理解与实现。
递归分为直接递归和间接递归,就简单分享一下两个小的直接递归。

对于递归的概念,其实你可以简单的理解为自己定义自己,记得小时候看过一部电视剧《狼毒花》,里面主角叫做“常发”,但是个文盲,老师问他叫什么,他说“常发”。“哪个常?”“常发的常啊!”“哪个发?”“常发的发啊!”结果第二节课老师就让一群小朋友一起喊“常发的常,常发的发,傻瓜的傻,傻瓜的瓜”。言归正传,显然在多数情况下递归是解释一个想法或者定义的一种合理方法。在思想上递归类似于数学中曾经学过的数学归纳法。

递归的实现:
递归的实现要注意有两点:一个递归的选项和一个非递归的选项,后者成为基础情形(base case)。基础情形是递归的终结情形,没有基础情形或者处理不好都会导致无穷递归,这是我们不想要的结果。递归实现起来最关键的是处理好基础情形。 结合具体事例在说一下递归回溯的过程。

其实A方法调用B方法,我们很容易理解!

◆递归就是: A方法调用A方法!就是自己调用自己

◆利用递归可以用简单的程序来解决一些复杂的问题。 它通常把一个大型复杂的问题层层转化为-个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

◆递归结构包括两个部分:

    ◆递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。◆递归体:什么时候需要调用自身方法。

Demo:

1、爬楼梯算法:已知一个楼梯有n个台阶,每次可以选择迈上一个或者两个台阶,求走完一共有多少种不同的走法。

package leetcode;public class ClimbStairs {
//  ************************************************
//递归public int climbStairs(int n) {int i=1;if(n<=0)return 0;if(n==1){return i;}if(n==2){i++;return i;}elsereturn climbStairs(n-1)+climbStairs(n-2);}
//**********************************************public static void main(String []args){ClimbStairs cs=new ClimbStairs();int a =cs.climbStairs(4);System.out.println(a);}}

递归函数有返回值的比没有返回值的麻烦一点,因为一个函数只有一个返回值,但是递归还要求有基础情形的存在,所以还必须有if判断来终止递归。所以在每一个if或者else后边都有一个return,这样保证函数在任何一种情况下都有且仅有一个返回值。
分析一下这个算法:
A:如果有0个台阶,那么有0种走法,这个不用多说;
B:如果有1个台阶,那么有1种走法;
C:如果有2个台阶,那么有2种走法(一次走1个,走两次;一次走两个);
以上的B和C就是基础情形。
D:接下来就是递归了,如果台阶数目多于2个,那么首先第一步就有两种选择:第一次走1个,或者第一次走两个。这样除了第一次后边的走法就有了两种情形:climbStairs(n-1)和climbStairs(n-2)。这样一直递归下去,直到出现到了基础情形(即n=1或n=2的情形),递归到这个地方(基础情形),然后开始回溯 ,这就是所说的和递归密切相关的“回溯”了。回溯,顾名思义就是从结果倒着回去,找到整个过程,进而分析这个路径或者说是实现的过程。

需要注意的是,这个算法实现思路上简单,但是复杂度并没有降低,还牵扯回溯保存堆栈问题(其实递归的设计尽量避免这种嵌套两个的递归方式(climb(n)中包含climb(n-1)和climb(n-2)),这种操作会使得堆栈开辟空间随着n的增大以指数型增长,最终程序很容易崩溃),而且在台阶数目多到一定数量的时候会越界(走法次数会超出int的范围),所以递归程序很大程度上就是思想实现设计上简单理解一些。

public class hello{public static void main(String[] args){int n=5;System.out.println("第"+n+"个月的兔子总数是"+funs(n));}private static int funs(int n){ if(n==1||n==2)       return 1;else               return funs(n-1)+funs(n-2);                                }}

public class hell {public static void main(String[] args){int n=6;System.out.println("第"+n+"个月的兔子总数是"+funs(n,"入口"));}private static int funs(int n,String s){ System.out.println("初始化的n的值="+n);System.out.println("n值来源="+s);if(n==1||n==2) { return 1;}else {int i=funs(n-1,"第一次计算");int i1=funs(n-2,"第二二二次计算");System.out.println("///*************///");System.out.println("n-1结果="+i);System.out.println("///*************///");System.out.println("n-2结果="+i1);return i+i1;   }}}
初始化的n的值=6
n值来源=入口
初始化的n的值=5
n值来源=第一次计算
初始化的n的值=4
n值来源=第一次计算
初始化的n的值=3
n值来源=第一次计算
初始化的n的值=2
n值来源=第一次计算
初始化的n的值=1
n值来源=第二二二次计算
///*************///
n-1结果=1
///*************///
n-2结果=1
初始化的n的值=2
n值来源=第二二二次计算
///*************///
n-1结果=2
///*************///
n-2结果=1
初始化的n的值=3
n值来源=第二二二次计算
初始化的n的值=2
n值来源=第一次计算
初始化的n的值=1
n值来源=第二二二次计算
///*************///
n-1结果=1
///*************///
n-2结果=1
///*************///
n-1结果=3
///*************///
n-2结果=2
初始化的n的值=4
n值来源=第二二二次计算
初始化的n的值=3
n值来源=第一次计算
初始化的n的值=2
n值来源=第一次计算
初始化的n的值=1
n值来源=第二二二次计算
///*************///
n-1结果=1
///*************///
n-2结果=1
初始化的n的值=2
n值来源=第二二二次计算
///*************///
n-1结果=2
///*************///
n-2结果=1
///*************///
n-1结果=5
///*************///
n-2结果=3
第6个月的兔子总数是8

n=1 结果为1 n=2 结果为1 n=3 结果为2 n=4 结果为3 n=5 结果为5

java的递归详细讲解相关推荐

  1. Java语言基础详细讲解

    就像人与人之间交流使用的语言需要遵循一定的语法规则一样,Java语言也离不开特定语法的支持,如基本语法.数据类型.变量.常量.运算符与表达式.类型转换和输入输出等,只不过这些语法要比日常生活中语言的语 ...

  2. Java定时任务最详细讲解(普通项目,Spring项目)

    文章目录 一.前言 二.普通项目 1.Timer 2.ScheduledExecutorService (1)scheduleAtFixedRate (2)scheduleWithFixedDelay ...

  3. java循环输入_【图文+视频新手也友好】Java一维数组详细讲解(内含练习题答案+详解彩蛋喔~)...

    [新手友好型视频+图文] 全面讲解Java一维数组(内含带答案和讲解的练习题彩蛋喔) 看完即上手!更有详解版练习题来帮你加深印象~~ 一.视频讲解 一维数组详解https://www.zhihu.co ...

  4. Java split方法详细讲解

    今天是圣诞节,我是中国人,无视圣诞节. 文章可能有点长,看下来必定有所收获. 没有学过正则表达式的去b站看,一个半小时应该可以看完,要看请点这里 这是必备的前置技能,不懂得话没法真正明白split用法 ...

  5. abnf java实现_详细讲解如何利用Java实现组合式解析器?

    简介:Ward Cunningham 曾经说过,干净的代码清晰地表达了代码编写者所 想要表达的东西,而优美的代码则更进一步,优美的代码看起来就像是专门为了 要解决的问题而存在的.在本文中,我们将展示一 ...

  6. Java Set接口详细讲解 TreeSet的定制排序和自然排序

    Set接口概述 Set接口是Collection的子接口,set接口没有提供额外的方法 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败. Set 判断 ...

  7. 【JAVA字符串最详细讲解】

    JAVA字符串 一.String类 1.声明字符串 2.创建字符串 二.连接字符串 1.连接多个字符串 2.连接其他数据类型 三.获取字符串信息 1.获取字符串长度 2.字符串查找 3.获取指定索引位 ...

  8. java 零拷贝详细讲解

    文章目录 一.传统IO 二.零拷贝 1.通过DirectByteBuffer优化 2.通过 linux 2.1 sendFile优化 3.linux 2.4优化 三.java实现零拷贝 1.mmap ...

  9. java里throws详细讲解,基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...

最新文章

  1. python-docx表格设置实线_python docx加入表格 在表格中加图,设置框线
  2. JAVA虚拟机内存不够解决办法
  3. python写入中文、用utf-16编码得出二进制字节串_在python中将unicode UTF16数据写入文件时出现问题...
  4. Left join后用and和where的区别
  5. python 梯度提升树_机器学习:梯度提升算法|python与r语言代码实现
  6. centos使用vnc实现远程访问图形化界面
  7. 《量化金融R语言初级教程》一2.6 如果方差不够用
  8. 华为机试HJ82:将真分数分解为埃及分数
  9. 工作4年,我从阿里巴巴辞职到了国企
  10. mysql数据库过滤数据_MySQL数据库常规操作一些简单绕过过滤的方法
  11. 鸿蒙分布式内核,华为发布鸿蒙:基于微内核的全场景分布式OS
  12. Kubernetes详细笔记
  13. css宋体代码_css怎么设置字体为宋体
  14. 凤凰网科技频道定位和主要内容
  15. 高级程序员的思维模式
  16. 第一次使用scrapy爬豆瓣top250 报错 AttributeError Requset has no attribute dont_filter 和 meta
  17. 易语言 多线程,等待所有线程执行完毕后操作
  18. 乐动机器人 2D DTOF激光雷达 LD06、LD19驱动包开源仓库分享
  19. 辗转相除法和更相减损法原理和算法
  20. obd 与服务器 通讯协议,经典   OBD-2是什么及接口针脚定义和通信协议

热门文章

  1. Python使用pandas_ml输出混淆矩阵以及从混淆矩阵衍生出来的其他指标:TP、TN、FP、FN、TPR、TNR(SPC)、PPV、NPV、FPR、FDR、FNR、ACC、F1、MCC等
  2. 以太网适配器和隧道适配器
  3. 虹科教您 | 理解微波射频中的特性阻抗、VSWR 和反射系数
  4. 某品牌服务器raid5阵列删除数据恢复过程分析
  5. 佛山c语言培训学校,佛山C语言培训:如何轻松学习C语言?
  6. 基于PHP的快递查询免费开放平台案例-快宝开放平台
  7. 西北乱跑娃 --- bottle框架部署pytorch模型
  8. iOS监控-野指针定位
  9. 阿里云Apsara Clouder专项技能认证-实现调用API接口-学习笔记
  10. 降温出门怎么穿?蕉内热皮重塑你对秋冬基本款的想象