【2.0 递归 Recursion 01】
【介绍】
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】的更多相关文章
- 【3.0 递归 Recursion 02】
[递归:阶乘] 1.寻找基本情况 对于阶乘而言,最基本的情况就是0!和1!,二者的结果都是1 我们不妨现在方法中写下这个情况,帮助我们跳出递归 if(i<=1){ return 1 ; } 接下 ...
- Atitit 循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate).
Atitit 循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 1.1. 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称之为循环. ...
- 循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate)的区别
表示“重复”这个含义的词有很多, 比如循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称 ...
- 003_循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate)的区别
表示“重复”这个含义的词有很多, 比如循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称 ...
- 数据结构与算法--递归(recursion)
递归的概念 简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁. 递归调用机制 我列举两个小案例,来帮助大家理解递归 1.打印问题 ...
- 算法与数据结构基础 - 递归(Recursion)
递归基础 递归(Recursion)是常见常用的算法,是DFS.分治法.回溯.二叉树遍历等方法的基础,典型的应用递归的问题有求阶乘.汉诺塔.斐波那契数列等,可视化过程. 应用递归算法一般分三步,一是定 ...
- 《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. ...
- 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 ...
- 【数据结构与算法Python版学习笔记】递归(Recursion)——优化问题与策略
分治策略:解决问题的典型策略,分而治之 将问题分为若干更小规模的部分 通过解决每一个小规模部分问题,并将结果汇总得到原问题的解 递归算法与分治策略 递归三定律 体现了分支策略 应用相当广泛 排序 查找 ...
随机推荐
- PHP反序列化字符串逃逸
通过CTF比赛了解PHP反序列化,记录自己的学习. 借用哈大佬们的名言 任何具有一定结构的数据,如果经过了某些处理而把结构体本身的结构给打乱了,则有可能会产生漏洞. 0CTF 2016piapiapi ...
- [C#] (原创)一步一步教你自定义控件——06,MaskLayer(遮罩层)
一.前言 技术没有先进与落后,只有合适与不合适. 本篇的自定义控件是:遮罩层(MaskLayer). 遮罩层对软件的美观与易用性上的提高是很大的,在日常使用过程中也会经常看到各种遮罩层,虽然WinFo ...
- vue-axios插件、django-cors插件、及vue如何使用第三方前端样式库:element/jQuery/bootstrap
目录 一.vue的ajax插件:axios 1.安装axios 2.axios参数 二.CORS跨域问题(同源策略) 1.Django解决CORS跨域问题方法 三.前端请求携带参数及Django后台如 ...
- 更换 grub 主题
默认的 grub 界面比较简陋 然后突然有想法了,想换个主题 具体操作 1.下载 grub 主题包 去这个地址下载主题(应该是这个地址): https://www.gnome-look.org/bro ...
- ElasticSearch 数据建模
公号:码农充电站pro 主页:https://codeshellme.github.io 通常在使用 ES 构建数据模型时,需要考虑以下几点: 字段类型 是否需要搜索与分词 是否需要聚合与排序 是否需 ...
- brew安装Nginx
目录 安装流程 常用命令记录 典型配置方式 查看启动状态是否有报错 php 启动 参考 安装流程 这里使用 brew 来安装软件. 安装 brew install nginx 查看安装信息(经常用到, ...
- 在不使用外延层的同轴半绝缘衬底材料上制作4H-SIC横向双重注入金属氧化物半导体场效应晶体管
在不使用外延层的同轴半绝缘衬底材料上制作4H-SIC横向双重注入金属氧化物半导体场效应晶体管 杂志:日本应用物理杂志 在不使用外延层在同轴的半绝缘SIC衬底上制作4H-SIC横向双重注入金属氧化物 ...
- PAT-1167(Cartesian Tree)根据中序遍历序列重建最小堆
Cartesian Tree PAT-1167 一开始我使用数组进行存储,但是这样可能会导致无法开足够大的数组,因为树如果是链表状的则无法开这么大的数组(虽然结点很少). 正确的解法还是需要建树,使用 ...
- Excel_不打开文件进行跨工作簿查询
在使用Excel时,我们经常会遇到这种问题,我的数据源在表1里面,但是我要在表2里面做报表,用lookup和offset等公式都需要打开表1操作,否则就会报错.那么有没有办法在不打开表1的情况下在表2 ...
- Python学习笔记 CH1-4:从入门到列表
Python CH1 环境准备 因为已经有了C/C++.Java的基础,所以上手很快. 参考书:Eric Matthes -<Python编程 从入门到实践> 环境准备:python3.P ...