【Java学习笔记】递归

Java中关于递归(recursion)方法 java中关于递归(recursion)方法 阅读详情

递归(recursion)

思想:把一个复杂的问题拆分成一个简单问题和子问题,子问题又是更小规模的复杂问题,循环往复

本质:栈的使用

递归的注意事项

  • (1)需要有递归出口,否者就会无限递归造成栈溢出

  • (2)每一次递归调用都会生成一个新的栈空间(即:执行一个方法时,就创建一个新的受保护的独立空间(栈空间)),代码继续从上往下执行,如果符合条件就会一直递归,直到递归出口,最后一层一层返回值,完成函数的调用

  • (3)方法的局部变量都是独立的,不会相互应影响

  • (4)当一个方法执行完毕,或者遇到return就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕


递归的内存机制分析

代码示例


public class Recursion01 {
    public static void main(String[] args) {
        Tt1 = newT();
        t1.test(4);//输出什么? n=2 n=3 n=4
    }
 }

class T {
    public void test(int n) {
        if (n > 2) {
            test(n- 1);
        }
        System.out.println("n=" + n);
    }
}

内存视图分析

在这里插入图片描述


递归实例

案例一:阶乘问题(factorial)

import java.util.Scanner;
public class recursion {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        object object = new object();
        System.out.print("input a number:");
        long n = input.nextLong();
        long result = object.factorial(n);
        System.out.print("factorial(" + n + ") is:" + result);
    }
}

class object{
    public long factorial(long n){
        if(n == 1){
            return 1;
        }
        else{
            return n * factorial(n - 1);
        }
    }
}

案例二:猴子吃桃问题

有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!以后每天猴子都吃其中的一半,然后再多吃一个。当到第 10 天时,想再吃时(即还没吃),发现只有 1 个桃子了。问题:最初共多少个桃子?

public class recursion {
    public static void main(String[] args){
        method t = new method();
        int res = t.peach(1);
        System.out.print(res);
    }
}

class method{
    public int peach(int day){
        if(day == 10){
            return 1;
        } else if(day >= 1 && day <= 9){
            return ( peach(day + 1) + 1 ) * 2;   // 枚举每天的情况找规律得到
        }else{
            return -1;
        }
    }
}

案例三:斐波那契数列

1,1,2,3,5,8,13…给你一个整数 n,求出它的值是多少?

特点:从第三个数开始,后一个数等于前面两个数之和

//斐波那契数列:1,1,2,3,5,8,13...

public class recursion {
    public static void main(String[] args){
        method t = new method();
        int res = t.fibonacci(10);
        System.out.print(res);
    }
}

class method{
    public int fibonacci(int n){
        if(n == 1 || n == 2){
            return 1;
        }
        else{
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

//输出:55

案例四;汉诺塔

有趣的小故事

  • 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序攥着 64 片圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
  • 假如每秒钟移动一次,共需多长时间呢?移完这些金片需要 5845.54 亿年以上,太阳系的预期寿命据说也就是数百亿年。真的过了 5845.54 亿年,地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。

在这里插入图片描述

思路分析:可以把这个问题拆分

  • (1)把最底层移动到C塔

  • (2)把上面的n-1个圆盘看作整体,移动到B塔

  • (3)上面的n-1个圆盘又可以拆分成如上的问题,不断递归下去

//斐波那契数列:1,1,2,3,5,8,13...

public class recursion {
    public static void main(String[] args){
        tower t = new tower();
        t.move(3, 'a', 'b', 'c');
    }
}

class tower{
    // 移动的圆盘个数, A塔 ,B塔 , C塔
    public void move(int num, char a, char b, char c){
        if(num == 1){
            System.out.println(a + "->" + c);
        }else{
            // 把上面的 n-1 个圆盘从 a塔 移动到 b塔,中间借助 c 塔
            move(num -1, a, c, b);
            // 把最下面的圆盘移动到 c塔
            System.out.println(a + "->" + c);
            // 把 b塔 的所有盘移动到 c塔,中介借助 a塔
            move(num -1, b, a, c);
        }
    }
}

//输出
a->c
a->b
c->b
a->c
b->a
b->c
a->c

迷宫问题

在这里插入图片描述

思路:运用二维数组表示迷宫,初始位置为(1,1),走到出口处,标记路线

  • 0表示可以走(还未被标记)

  • 1表示障碍物

  • 7表示可以走(被标记后)

  • 3表示走过,但是走不通是死路

代码示例

public class migong {
    public static void main(String[] args){

        int[][] map = new int[8][7];

        //标记墙面的部分
        for(int i = 0; i < 8; i++){
                map[i][0] = 1;
                map[i][6] = 1;
            }
        for(int i = 0; i < 7; i++){
            map[0][i] = 1;
            map[7][i] = 1;
        }
        map[3][1] = 1;
        map[3][2] = 1;

        // 回溯测试:辅助理解方法调用完成后栈空间释放,是如何返回的
//        map[2][2] = 1;

        // 封闭路径,测试结果
//        map[2][1] = 1;
//        map[2][2] = 1;
//        map[1][2] = 1;

        // 调用方法
        t finder = new t();
        finder.findway(map,1,1); // 起点是(1,1)
        //打印找路结果
        for(int i = 0; i < map.length; i++){
            for(int j = 0; j < map[i].length; j++){
                System.out.print(map[i][j] + " ");
            }
            System.out.println("");
        }

    }
}


class t{
    public boolean findway(int[][] map, int i, int j){
        // 找路策略:下右上左

        // 如果找到了就出口返回 true
        if(map[6][5] == 7){
            return true;
        }else{
            if(map[i][j] == 0){
                //假设当前点使用探路策略可以走通,就说明可以和之前的点衔接起来构成一条可以走通的路线
                map[i][j] = 7;

                // 接着使用找路策略开始探路,验证当前点开始是否可以走通

                //往下走
                if(findway(map, i+1, j)){
                    return true;
                }
                // 往右走
                else if(findway(map, i, j+1)){
                    return true;
                }
                // 往上走
                else if(findway(map, i-1, j)){
                    return true;
                }
                // 往左走
                else if(findway(map, i, j-1)){
                    return true;
                }
                // 都走不通,走过了但是走不通就标记为 3
                else{
                    map[i][j] = 3;
                    return false;
                }
            }else{  // 此时 map[i][j] = 1, 7, 3 ; 7 表示测试过了就不要再重复测试
                return false;
            }
        }
    }
}

理解:没走到一个点,就会递归的使用下->右->上->左的方式进行探路,如果都走不通就会返回到上一次递归调用,继续探路,指导找到出口为止

AutoCAD二次开发(.Net)之XData 对于CAD中的实体进行筛选等操作,常常会用到实体的XData属性,下面介绍一下实体的XData的增删改。 //XData的新增,修改跟新增一样,new一个ResultBuffer,赋值即可 Document doc=Application.DocumentManager.MdiActiveDocument; using (DocumentLock dl = doc.LockDocument()) { using (Transaction trans = doc.TransactionManager.S. 阅读详情

相关推荐

高速PCB差分对布线仿真实战案例

差分对布线是高速PCB设计的关键环节,直接影响信号完整性与EMI性能。本文结合实际项目,详解等长控制、阻抗匹配、间距优化等核心技巧,并通过仿真工具验证眼图、串扰和时序裕量,助力工程师规避常见高速pcb设计陷阱。

weixin_29092787的博客 349

Java中的递归(recursion)方法----简单介绍加演示

递归方法简介: 一个方法体内调用它自身 方法递归包含了一中隐式循环,它会重复执行某段代码,但是这种执行无需循环控制。 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。 1.用递归求一个1-100的和 package demo; public class demo1 { public static void main(String[] args) { int n=100; demo1 demo1 = new demo1();

路宇的博客 4572

二维otsu算法python_OpenCV-Python系列之OTSU算法

上一个教程中,我们谈到了关于图像二值化的两种方法,一种是固定阈值法,另一种是自适应阈值法,总的来说,自适应阈值法在某些方面要由于固定阈值法,但还没完,这次我们将隆重介绍我们的重量级选手,也就是OTSU算法(又称为大津算法和最大类间方差法)。最大类间方差法是1979年由日本学者大津提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像...

weixin_28834169的博客 1426

1. 删除一个非空的目录 2. 移动一个非空的目录到另一个地方(剪切)。

// 1,删除一个非空的目录。并加强健壮性 private static void deleteFile(File file) { if (!file.exists()) { System.out.println("路径不存在"); return; } if (!file.isDirectory...

qq_38409944的博客 1567

LTSPICE仿真电路:(二十八)三极管厄利电压与输出特性曲线深度解析

本文深入解析了LTSPICE仿真电路中三极管的厄利电压与输出特性曲线,详细介绍了厄利电压的物理意义、仿真设置及实际应用。通过伏安特性曲线和厄利电压的分析,帮助读者理解三极管放大性能的关键参数,并提供了电路设计中的优化方案和故障排查技巧。

weixin_26899659的博客 149

卡尔曼滤波算法-Kalman Filter Algorithm

Kalman滤波是一种递归过程,主要有两个更新过程:时间更新和观测更新,其中时间更新主要包括状态预测和协方差预测,主要是对系统的预测,而观测更新主要包括计算卡尔曼增益、状态更新和协方差更新,因此整个递归过程主要包括五个方面的计算:1)状态预测;2)协方差预测;3)卡尔曼增益;4)状态更新;5)协方差更新; 用数学公式表示,如下: 状态预测:(1) 其中,X(k|k)是k时...

sunlin972913894的博客 2万+

【Java 基础篇】Java递归详解

本文详细介绍了Java中的递归原理、应用场景和实现方法。递归是一种强大的编程技术,能够解决复杂问题,简化代码逻辑,并实现高效的算法。通过定义终止条件和递归调用,我们可以实现递归函数来解决各种问题。需要注意的是,递归的使用需要谨慎,要确保终止条件和递归调用的条件正确,并避免陷入无限循环。希望本文对你理解和应用Java中的递归有所帮助!附:示例代码// 终止条件 if(n == 0) {return 1;} // 递归调用 return n * factorial(n - 1);int n = 5。

繁依Fanyi的博客 1万+

MFC 利用soap 调用web service

MFC 利用soap 调用web service

congjiaoyan3682的博客 785

java数据结构和算法——递归(Recursion)的介绍

一、递归(Recursion)的概念 递归就是方法自己调用自己,每次调用时传入不同的变量. 递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。 二、递归(Recursion)的调用机制 1、递归的调用机制示例图解如下: 2、递归的调用机制简单的示例代码如下: package com.rf.springboot01.dataStructure.recursion; /** * @description: 递归调用示例 * @author: xiaozhi * @create: 2020-07

小志的博客 2263

Gitee自动创建PR之——评审模式

一 创建PR的常规操作 本地更新主干(一般为master分支),基于主干新建一个分支并(如Dev分支)切换; 进行新的需求开发; 将这个分支推送到远端; 打开 Gitee ,进入创建 Pull Request 界面; 选定目标分支(及我们需要合并到主干分支的分支,一般即为我们的开发分支); 填写 Title 以及 Description; 点击提交 Pull Request。 二 更快的常见PR的方式— — 评审模式 现在 Gitee.

calm_encode的博客 2989

C3 模块与普通 Bottleneck 堆叠区别

维度普通 Bottleneck 堆叠C3 模块设计理念残差学习CSP + 特征分治信息路径单一路径双路径(主干 + bypass)融合方式相加(Add)拼接(Concat)+ 卷积计算效率较低高(通道减半)特征保留弱(多次非线性)强(直连保留原始信息)梯度传播单一主路径多样化、更稳定任务适配通用(分类为主)专为目标检测优化可扩展性有限极强(即插即用各种模块)实际性能基准线显著优于(尤其在小目标和效率方面)

浩瀚之水的专栏 107

Java版数据结构和算法学习笔记之线性结构递归篇

Java版数据结构和算法学习笔记之线性结构递归篇1. 递归和斐波那契1.1 斐波那契数列 1. 递归和斐波那契 1.1 斐波那契数列 斐波那契数列—百度百科

TingtingYang 216

【红外DDE算法】一种应用于高动态范围红外可视化的算法

【红外DDE算法】一种应用于高动态范围红外可视化的算法 - 这个算法背后的动机 - 展示这个算法的流程 - 然后讨论各个可调参数的意义。

sunwindl91181的博客 1682

JAVA学习笔记11:递归

递归可以理解成一个函数调用自己的过程。 递归头:为了防止递归程序死循环设置的,什么时候不用调用自身方法时就使用递归头。 递归尾:与递归头相反,即什么时候需要调用自身方法的时候就使用递归尾。 注意:就算没有递归头,java中递归不会无限的递归下去,递归太深,堆栈内存会溢出 循环效率比递归高,但是递归能做到的循环未必能做到。 例子: 来自 :https://www.sxt.cn/first-seaso...

TomCat的播客 158

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java学习笔记——递归

递归 概述 递归:指在当前⽅法内调⽤⾃⼰的这种现象。 递归的分类: 递归分为两种,直接递归和间接递归。 直接递归称为⽅法⾃身调⽤⾃⼰。 间接递归可以A⽅法调⽤B⽅法,B⽅法调⽤C⽅法,C⽅法调⽤A⽅法。 注意事项: 递归⼀定要有条件限定,保证递归能够停⽌下来,否则会发⽣栈内存溢出。 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发⽣栈内存溢出。 构造⽅法,禁⽌递归 举例 public class Demo01DiGui { public static void main(String[] args

JUN__TAO的博客 236

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

学习笔记分享-数据结构与算法-图-java表示图、DFS(递归、非递归实现)

学习笔记分享-数据结构与算法-图-java表示图、DFS(递归、非递归实现)

2301_81243975的博客 395

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【狂神说java学习笔记】六:java方法(方法的定义、调用、重载、参数传递、递归)

本文整理了狂神说Java课程的Java方法基础知识,包括方法的定义与调用、重载规则、可变参数和递归结构。

weixin_41637679的博客 377

Java学习笔记——方法递归

直接递归:方法调用自己这样使用直接递归,方法无限调用自己,无法终止,最终引起栈内存溢出,称为递归死循环间接递归:方法调用其他方法,其他方法又回调方法自己。

weixin_44456914的博客 518

java学习笔记8——递归

递归概念 递归:方法自己调用自己 -递归分为两种,直接递归和间接递归 -直接递归称为方法自身调用自己 -间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法 ==注意事项:== -递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内溢出 -在递归中虽然有限定条件,但是递归次数不能太多。否则也会溢出 -构造方法,禁止递归 递归的使用前提: 当调用方法的时候...

weixin_44388890的博客 238

JAVA递归学习笔记

递归:方法中定义调用方法本身。 注意事项: 1、递归一定要有出口,否则就是死循环。 2、递归次数不能太多,否则内存溢出。 3、构造方法不能递归使用。递归代码简单示例:public void show(int n){ if(n == 0){ System.exit(0); //设置程序出口

tjkj10的博客 595

【JAVA学习笔记】递归

递归–思想的学习 递归即是自己调用自己。 利用递归可以用简单的程序来解决一些复杂问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。 递归结构包含两个部分: 1. 递归头:什么时候不调用自身方法,如果没有头,将陷入死循环。 2. 递归体:什么时候需要调用自身方法。 简单示例:阶乘 public static void main(Stri

weixin_49563267的博客 204

Java学习笔记——方法的使用及递归问题

有关java方法的使用,方法的重载以及递归问题解题思路的一些总结

ShirleyZ1007的博客 397

Java进阶学习笔记61——方法递归

Java进阶学习笔记

CCH2024的专栏 679

java学习笔记15——递归

【公司基本上没有几个人我还在搬砖,我觉得这是福报。对面的福报。。。波及范围太大了。哈哈】 话说递归这玩意其实就是函数调函数,调用自己。在函数中就调用自己。说起来这也是一种循环,反复调用自己就必然需要结束条件,正如人的生命一样。下面举个简单的例子,还是我特么一年前写的python,见我的科学网博文【我之前科学网博文就是写技术博文的,后来改成文艺博文了】 直接放出来吧,我觉得也没有啥意思。无...

NLP与推荐算法 510

Java学习笔记-File类、递归

第一章 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。 1.2 构造方法 public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 public File(String parent, String child) :从父路径名字符串和子路径...

cyh0503的博客 2451

【JAVA 学习笔记】File类、递归

【File类、递归】 文章目录【File类、递归】第一章 File类绝对路径和相对路径1.2 构造方法1.3 常用方法获取功能的方法判断功能的方法创建删除功能的方法1.4 目录的遍历第二章 递归2.1 概述2.2 递归打印多级目录第三章 综合案例3.1 文件搜索3.2 文件过滤器优化3.3 Lambda优化 第一章 File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件...

lameraaa的博客 280
上一篇: 常见的努力陷阱,跳出死循环把孩子!!!
下一篇: 【Java学习笔记】方法重载
jackson凌
博客等级 码龄2年 476粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackson凌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值