【递归:阶乘】

1.寻找基本情况

对于阶乘而言,最基本的情况就是0!和1!,二者的结果都是1

我们不妨现在方法中写下这个情况,帮助我们跳出递归

if(i<=1){
return 1 ;
}

接下来,如果不是1或0,则进行阶乘运算

public static int Factorial (int i){
if(i<=1){
return 1 ;
}else {
return (i*Factorial(i - 1)) ;
}
}

思路很简单,我们从n开始放入,计算n!就需要(n-1)!,计算(n-1)!需要(n-2)!,以此递推到1!

下面是对于这次操作的栈的示意图(以5为例)

建立堆栈(递归的过程

开始执行的时候,是从Factoria(1)逐级返回,最终得到5*4!即返回的过程

【递归:三角数】

三角数就像是加法的“阶乘”,必然1+2+3+4...

首先还是先寻找最初始的情况,显然那就是1了

和阶乘一样,我们也利用“堆栈——返回”的操作来进行三角数的计算

我们观察发现:出现一个模式即 T(n)= T(n –1)+ n 这种模式将有助于对三角数程序的递归进行程序编写。

public static int TrianNum(int i){
if(i<=1){
return 1 ;
}else {
return (i+TrianNum(i - 1)) ;
}
}

【斐波纳契数列 Fibonacci Numbers】

斐波那契数列:前两个数之后的每一个数都是前两个数的和

我们可以通过下面这个方程来描述斐波纳契数列

迭代的角度来看斐波那契数列:

为了计算任何斐波那契数“n”,我们需要知道斐波那契数“n -1”和“n -2”,对于迭代版本,我们从第一个数字(n = 0)开始

随后我们计算1,2两个数字,之后是2,3,然后是3,4...以此不断推进,那么可以按照这个思想得到下面这个算法

public static int FibIter(int n){
int prevl =0 , prev2 = 1 ;
int savePrev1 = 0 ;
for(int i = 0 ; i <n ; i ++){
savePrev1 = prev1 ;
prev1 = prev2 ;
prev2 = savePrev1 + prev2 ;
}
return prev1 ;
}

递归的角度来看斐波那契数列:

在之前的方程中,实质上已经包含的基本情况和递归步骤

我们可以得到在递归角度的如下代码:

public static int Fib(int n){
if(n == 0 ) {
return 0 ;
}
else if(n == 1 ) {
return 1 ;
//注意,这里是else if ,当第一个基本情况不满足时,才去判定第二个。当二者都不符合,再进入递归步骤
}else{
return Fib(n-1) + Fib(n-2) ; //就是这一步,实质上实现了F(n) = F(n-1) + F(n-2) 的操作
}

迭代递归两种方法得到的答案是一样的,但是运行的过程和核心是非常不同的

采用递归的思想进行计算时,先不断堆栈达到基本情况(0或1),然后再由基本情况向目标推进

【递归:函数功能定义 Functional Definitions】

我们经常会遇到用递归函数定义的问题——就像我们在斐波那契数列中看到的那样,问题的定义通常用数学的方法(方程)写成

就像这种形式的方程,我们便可以使用递归

在这种情况下,递归常常会比迭代更加直观

public static int FuncA(int n) {
if(n == 1 ){
return 4 ;
}else{
return (5* Func(n-1)+10);
}
}

【递归与数组 Recursion with Arrays】

递归还可以用于查找存储在数组中的最大值和最小值,让我们尝试一个寻找数组最大值的例子:

首先是找到基本情况,我们将假定将从当前元素开始遍历整个数组。基本情况是,当我们查看数组中的最后一个元素的时候————这时候我们已经知道了我们遍历了数组中的所有元素,所以我们从此跳出递归

那么递归步骤呢,这个其实很简单:我们将每个元素与当前存储的最大元素进行比较,如果当前正在查看的元素大于当前最大存储元素,则将该值更新为新的最大值

附:Math.max : Math.max(int a, int b),会返回a、b中的较大者,需要import java.lang.* ; 后使用


public static int maxArray(int [] array , int start){
if(start == array.lengrh - 1){
return array[start] ; //一个基本情况:仅有一个数字的数组,代表需要结束了
}else{
return (Math.max(array[start],maxArray(array,start + 1)));
}
}

可能光看代码比较抽象,来看看这张示意图:

【小结:递归的优缺点】

缺点:

•递归反复调用该方法,该方法在内存和处理时间方面会产生成本

•每次递归调用都会创建该方法的另一个副本(及其所有变量)

•这种方法的复制会消耗大量的内存空间

优点:

•如果我们对原始问题做一些细微的改变,就会更容易找到递归的解决方案

•有时,递归解决方案的运行速度会比迭代解决方案慢,不过,在大多数情况下,它只是稍微慢一些

•在许多情况下,递归解决方案比迭代解决方案更容易理解和编写代码

【3.0 递归 Recursion 02】的更多相关文章

  1. 【2.0 递归 Recursion 01】

    [介绍] Java的一个方法可以调用它自己,Java和所有编程语言都可以支持这种情况,我们把它叫做递归Recursion 递归方法是一种调用自身的方法 那么使用递归方法是是怎么样的呢,让我们看看下面这 ...

  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. webug4.0 打靶笔记-02【完结】

    webug4.0打靶笔记-02 3. 延时注入(时间盲注) 3.1 访问靶场 3.2 寻找注入点 貌似一样的注入点: ?id=1' --+ 3.3 判断输出位置 同前两关一样的位置,时间盲注应该不是这 ...

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

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

  8. 《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. ...

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

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

随机推荐

  1. 最佳搭档:利用 SSH 及其配置文件节省你的生命

    本文转载自最佳搭档:利用 SSH 及其配置文件节省你的生命 导语 SSH 协议是事实上的互联网基石之一.在 SSH 协议出现之前(1995 年由 Tatu Ylonen 设计),通过互联网远程登录其他 ...

  2. springCloud中的注册中心Nacos

    springCloud中的注册中心Nacos 三个模块: 1.注册中心 2.服务提供者(生产者) 提供服务 3.服务消费者(消费者)调用服务 流程:消费者和生产者都要向注册中心注册,注册的是二者中服务 ...

  3. Python3+PYQT5 实现并打包exe小工具(2)

    前言:前篇已经通过python代码实现了逻辑,传送门:https://www.cnblogs.com/jc-home/p/14447850.html 现在后篇记录的是打包成exe的方式给项目其他同事使 ...

  4. oracle can't kill session

    oracle 在杀会话时,会出现杀不掉的情况. 原因是在回滚大事物   解决方法: alter system disconnect session 'sid, serial#' immediate; ...

  5. 资源授权?对OAuth2.0的一次重新认识的过程

    什么是OAuth? OAuth一个开放的授权标准,允许用户在不提供关键信息(如账号,密码)给第三方应用的前提下,让第三方应用去访问用户在某网站上的资源(如头像,用户昵称等). OAuth分为OAuth ...

  6. java帝国的诞生

    Java : 一个帝国的诞生 C语言帝国的统治 现在是公元1995年, C语言帝国已经统治了我们20多年, 实在是太久了. 1972年, 随着C语言的诞生和Unix的问世, 帝国迅速建立统治, 从北美 ...

  7. 《C++ Primer》笔记 第6章 函数

    任意两个形参都不能同名,而且函数最外层作用域中的局部变量也不能使用与函数形参一样的名字(形参就相当于该函数的局部变量). 形参名是可选的,但是由于我们无法使用未命名的形参,所以形参一般都应该有个名字. ...

  8. POJ-3159(差分约束+Dijikstra算法+Vector优化+向前星优化+java快速输入输出)

    Candies POJ-3159 这里是图论的一个应用,也就是差分约束.通过差分约束变换出一个图,再使用Dijikstra算法的链表优化形式而不是vector形式(否则超时). #include< ...

  9. Hadoop的常用命令

    注:hadoop的使用命令包含 hadoop fs 开头 or hdfs dfs开头 等多种形式来操作. 这里以hadoo fs的形式来介绍在这些命令 1.列出根目录下所有的目录或文件 hadoop ...

  10. webstorm2020.3安装破解教程

    免责声明:本教程及相关附件仅限于学术交流,不能用于商业以及违法用途,请于下载后24小时内删除!如产生法律纠纷,一切与本人无关,呼吁各位小伙伴支持下正版软件.本文如有侵权,请联系小编删除之. 该操作是用 ...