【介绍】

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. how to close macos eject icon from menu bar

    how to close macOS eject icon from the menu bar close eject https://apple.stackexchange.com/question ...

  2. Apache 低版本不支持 WebSocket

    Apache 低版本不支持 WebSocket Apache HTTP Server Version 2.4 Apache Module mod_proxy_wstunnel https://http ...

  3. 关于TCP的Total Length

    TCP/IP传输层 文档 随便找了个发送的TCP: 70 89 cc ee 84 2c 3c 2c 30 a6 a2 d0 08 00 45 00 00 4c c7 a8 40 00 80 06 00 ...

  4. js滚轮事件兼容写法

    /** * 简易的事件添加方法 */ define(function(require, exports, module) { exports.addEvent = (function(window, ...

  5. 谁能成为数据储存领域领头羊?永久数据存储--NGK的终极使命!

    区块链的目的是永远存储交易网络的历史.NGK技术团队能够永久存储其去中心化账本的副本.这是其日后能进行审计关键.一些著名的团队,如Solana和SKALE,现在正在为此与NGK进行最后的集成,我们预计 ...

  6. [转]ROS中使用message_filters进行多传感器消息同步

    转:http://www.rosclub.cn/post-1030.html 最近实验室老师在做一个多传感器数据采集实验,涉及到了消息同步.所以就学习了ROS官网下的消息同步工具message_fil ...

  7. 12_MySQL如何对查询结果进行排序

    本节所涉及的sql语句: -- 排序关键字 SELECT empno,ename,hiredate FROM t_emp ORDER BY hiredate DESC; -- 排序字段相同的情况 SE ...

  8. ElasticSearch 聚合分析

    公号:码农充电站pro 主页:https://codeshellme.github.io ES 中的聚合分析(Aggregations)是对数据的统计分析功能,它的优点是实时性较高,相比于 Hadoo ...

  9. Django Static与Media

    关于Django中Static和Media的设置问题(尤其是css和js静态文件加载的问题),网上有很多回答,但是发现有相当一部分回答并不能解决问题.有的可能是Django版本问题,有的是把media ...

  10. JavaScript疑难点

    什么是闭包 我个人理解闭包就是函数中嵌套函数,但是嵌套的那个函数必须是返回值,才构成闭包: //标准的闭包 function fn(){ var i=1; return function fnn(){ ...