【介绍】

Java的一个方法可以调用它自己,Java和所有编程语言都可以支持这种情况,我们把它叫做递归Recursion

递归方法是一种调用自身的方法

那么使用递归方法是是怎么样的呢,让我们看看下面这段代码

(由于复制粘贴代码还要考虑排版,这里就上图了)

结果是程序会一直在调用这个方法,直到内存不足而停止(无限套娃)

【概念】

方法反复调用自身的概念称为递归

方法会不断调用自身,直到达到某些停止条件为止,有点像循环语句

在没有停止条件的情况下,程序将循环运行,直到计算机(Java虚拟机)内存不足(拒绝分配更多的内存)为止

虽然递归可能显得浪费甚至效率低下,但它在计算机科学和数学中是一个非常重要的概念

递归更像是一种思想,我们需要打破原有的“迭代”的思维定势(for,while)

为了帮助可视化“递归”,我们将使用一个称为堆栈 Stack的通用概念

堆栈基本上像自助餐厅中的托盘容器一样工作。它只有两个操作:

Push:你可以把某个东西压到栈上

Pop:你可以从堆栈的顶部弹出一些东西

First In Last Off

通过下面这张图感受一下

有的人说这就像弹匣一样,拉出来装Push然后从第一发开始射击Pop

【堆栈和方法 Stacks and Methods】

当你运行一个程序时,计算机会为你创建一个堆栈

每次调用方法时,该方法都会放在堆栈的顶部

当方法返回或退出时,该方法将从堆栈中弹出

【堆栈和递归 Stacks and Recursion】

每次调用方法时,都将该方法推入堆栈

每次方法返回或退出时,都将方法弹出堆栈

如果一个方法递归地调用自己,您只需将该方法的另一个副本压入堆栈

对于下面的这个简单程序:

public class Recursion1V0{
public static void main (String args[]) {
count(0);
System.out.println();
}
public static void count (int index) {
System.out.print(index);
if (index < 2) count(index+1);
}
}

我们将这个过程可视化之后便是这样

如果我们把代码改成

public class Recursion1V0{
public static void main (String args[]) {
count(0);
System.out.println();
}
public static void count (int index) { if (index < 2) count(index+1);
System.out.print(index); //注意这里!
}
}

此时的输出是2 1 0 为什么呢,我们回忆一下堆栈的Push和Pop,就知道为什么了(FirstIn,LastOff)

我们需要一个方法执行结束(return好了),再执行接下来的操作

count(0)到count(1)到count(2),结束执行,随后执行System.out.print(index),分别打印210

【两种类型的递归】

1.直接递归 Direct recursion

方法直接包含对自身的引用或调用

2.间接递归 Indirect Recursion

一个方法调用另一个方法,该方法最终调用原始方法(比如A方法调用B方法,B方法调用A方法)

递归计算通过使用相同问题的解决方案来解决问题,但是具有更简单的值。我们称此为递归步骤 recursive step

为了使递归终止或停止,还必须有最简单值的特殊情况,我们称之为基本情况base case/anchor case/stopping condition

基本情况是为输入参数的一个或多个已知值指定方法值的情况

递归步骤(或归纳步骤)是根据先前定义的值定义对参数的当前值所采取的操作

为了执行递归,我们必须考虑以下两个方面

1.如何解决最简单的问题

2.给定一个更复杂的问题实例,如何使其更像最简单的实例?即如何使它更接近问题的最简单实例(使其像基本情况一样)?

【三步使用递归 Three Steps to Recursive Success 】

动手试试,我们写一个程序来检测字符串是否是回文(比如NAVAN)

1.减少 Reduction ——使问题变小

可以直接检测首尾的字符,如果它们是相同的,那么我们就删除它们(如果一开始就是回文如NAVAN,那么删除后得到的部分也是回文AVA)

2.基本情况 Base Cases ——处理简单的值,关键是找到最简单的情况的解决方案

比如有下面几个情况

1.最后没有字符了——是回文

2.最后剩下一个字符——是回文

3.最后剩下两个字符且二者不是同一个字符——不是回文

3.执行 Implement ——结合基本情况与步骤

【2.0 递归 Recursion 01】的更多相关文章

  1. 【3.0 递归 Recursion 02】

    [递归:阶乘] 1.寻找基本情况 对于阶乘而言,最基本的情况就是0!和1!,二者的结果都是1 我们不妨现在方法中写下这个情况,帮助我们跳出递归 if(i<=1){ return 1 ; } 接下 ...

  2. Atitit  循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate).

    Atitit  循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 1.1. 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称之为循环. ...

  3. 循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate)的区别

    表示“重复”这个含义的词有很多, 比如循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称 ...

  4. 003_循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate)的区别

    表示“重复”这个含义的词有很多, 比如循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称 ...

  5. 数据结构与算法--递归(recursion)

    递归的概念 简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁. 递归调用机制 我列举两个小案例,来帮助大家理解递归 1.打印问题 ...

  6. 算法与数据结构基础 - 递归(Recursion)

    递归基础 递归(Recursion)是常见常用的算法,是DFS.分治法.回溯.二叉树遍历等方法的基础,典型的应用递归的问题有求阶乘.汉诺塔.斐波那契数列等,可视化过程. 应用递归算法一般分三步,一是定 ...

  7. 《javascript高级程序设计》第七章 递归recursion

    7.1 递归7.2 闭包 7.2.1 闭包与变量 7.2.2 关于this 对象 7.2.3 内存泄漏 7.3 模仿块级作用域7.4 私有变量 7.4.1 静态私有变量 7.4.2 模块模式 7.4. ...

  8. HDU 4370 0 or 1 (01规划)【Dijkstra】||【spfa】

    <题目链接> 题目大意: 一个n*n的01矩阵,满足以下条件 1.X12+X13+...X1n=12.X1n+X2n+...Xn-1n=13.for each i (1<i<n ...

  9. 【数据结构与算法Python版学习笔记】递归(Recursion)——优化问题与策略

    分治策略:解决问题的典型策略,分而治之 将问题分为若干更小规模的部分 通过解决每一个小规模部分问题,并将结果汇总得到原问题的解 递归算法与分治策略 递归三定律 体现了分支策略 应用相当广泛 排序 查找 ...

随机推荐

  1. nginx proxy

    listen 80; server_name localhost; # 访问"localhost"的全部请求会被转发到"localhost:81" # loca ...

  2. vue农历日历

    <template> <div class="calendar-main"> <div class="choose_year"&g ...

  3. linux cd root directory

    linux cd root directory https://www.cyberciti.biz/faq/how-to-change-directory-in-linux-terminal/ htt ...

  4. 使用 mask 实现视频弹幕人物遮罩过滤

    经常看一些 LOL 比赛直播的小伙伴,肯定都知道,在一些弹幕网站(Bilibili.虎牙)中,当人物与弹幕出现在一起的时候,弹幕会"巧妙"的躲到人物的下面,看着非常的智能. 简单的 ...

  5. 16_MySQL聚合函数的使用(重点,建议大家多动手操作)

    本节所涉及的SQL语句 -- 聚合函数 SELECT AVG(sal+IFNULL(comm,0)) AS avg FROM t_emp; -- SUM SELECT SUM(sal) FROM t_ ...

  6. MYSQL安全模式"sql_safe_updates"设置update和delete不带where的操作限制

    前言 在数据库操作中,如果在update和delete没有加上where条件,数据将会全部修改. 不只是初识mysql的开发者会遇到这个问题,工作有一定经验的开发者有时难免也会忘记写入where条件. ...

  7. Vue前端项目的搭建流程

    1.  安装Vue和Nodejs 2.  创建项目 vue create eduonline-web

  8. JUnit5学习之七:参数化测试(Parameterized Tests)进阶

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. react入个门

    起步 react 特点 不使用模板 不是一个mvc框架 响应式 轻量级的js库 原理 虚拟dom 将dom抽象成js对象 diff算法 搭建开发环境 react.js 核心文件 react-dom.j ...

  10. 二叉树、平衡二叉树、红黑树、B树、B+树与B*树

    转: 二叉树.平衡二叉树.红黑树.B树.B+树与B*树 一.二叉树 1️⃣二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图: 基于二叉查找树的这种特点,在查找某个节点 ...