【递归:阶乘】

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. 教你玩转CSS Overflow

    CSS 布局 - Overflow CSS overflow 属性用于控制内容溢出元素框时显示的方式. <style> #overflowTest { background: #4CAF5 ...

  2. Java 优雅地退出程序

    本文转载自Java 优雅地退出程序 导语 很多情况下,我们的程序需要在操作系统 后台 一直运行,这在程序代码里的实现就是用死循环 ( while (true) ) 来实现的.但是,这样会出现一个问题, ...

  3. 修改yapf中的列宽限制值

    yapf是一款由Google开源的Python代码自动格式化工具,它根据PEP 8规范可以帮我们自动格式化我们的代码,让代码更规范.更漂亮.但是其中最大列宽被限制为80,如果超过80,在格式化时就会被 ...

  4. sun公司和apache使用ftpclient的区别

    最近因为使用FTP实现上传下载,因为已经有前辈使用了,照着敲了一遍(绝对没有复制粘贴啊,发誓).但是今天突然发现FTPClient还不一样,仔细看了看,一个是sun.net.ftp.FtpClient ...

  5. SpringCloud之服务网关

    1.zuul 1.1定义 zuul叫路由网关,它包含对请求的路由和过滤的功能. 路由负责将外部的请求转发到具体的微服务实例上,是实现外部访问统一入口的基础.而过滤是负责对请求的处理过程进行干预,是实现 ...

  6. 1.3.1 apache的配置(上)

    Apache是比较常用的web服务器软件,用来解析HTTP网页.这里需注意,apache本身并不能解析php页面,它是用来配置解析http页面的.当然,作为一款最流行的web服务器软件,apache支 ...

  7. 使用lua-nginx模块实现请求解析与调度

    系统版本及需求: OS:CentOS 7.7.1908 OpenResty:1.15.8.2 目录 描述 安装配置 安装openresty 使用示例 HTTP请求复制 HTTP报文解析 总结 描述 l ...

  8. 100道Java高频面试题(阿里面试官整理)

    我分享文章的时候,有个读者回复说他去年就关注了我的微信公众号,打算看完我的所有文章,然后去面试,结果我后来很长时间不更新了...所以为了弥补一直等我的娃儿们,给大家的金三银四准备了100道花时间准备的 ...

  9. 树莓派4B安装官方Ubuntu20 Server版(64位)

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

  10. tcpdump后台抓包并输出给wireshark

    # 先进到/tmp 目录执行,方便Filezila 传输 # 开启抓包 nohup tcpdump -i eth0 -s0 -nnA 'port 22' -w dump22.pcap & [1 ...