Java方法的递归

Java方法的递归

  • 前言
  • 一、递归的概念
    • 示例
    • 代码示例
  • 二、递归执行过程分析
    • 代码示例
    • 执行过程图
  • 三、递归练习
    • 代码示例
      • 按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)
      • 递归求 1 + 2 + 3 + ... + 10
      • 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19
      • 求斐波那契数列的第 N 项
        • 斐波那契数列介绍


前言

Java方法的递归是指一个Java方法直接或间接地调用自身,以完成重复或嵌套的计算任务。递归常用于处理具有自相似性的问题,通过分解问题为更小、更简单的子问题来解决整个问题。递归方法需要明确定义递归终止条件,以防止无限循环。


一、递归的概念

一个方法在执行过程中调用自身, 就称为 “递归”.

递归相当于数学上的 “数学归纳法”, 有一个起始条件, 然后有一个递推公式.

递归是一种在方法内调用自身的编程技术。在使用递归时,方法会重复调用自身,每次调用时传递不同的参数,直到满足某个终止条件为止。

递归可以用于解决一些问题,特别是那些具有递归结构的问题。在这些问题中,解决方案可以通过将问题分解为更小的子问题来实现。每次递归调用都会处理一个子问题,直到达到基本情况,然后将子问题的解决方案组合起来得到原始问题的解决方案。

递归要求在每次调用时,传递给递归方法的参数应该与原始问题的参数有关,但规模更小。这样可以确保递归在每次调用时朝着基本情况前进,并最终达到终止条件。

递归的基本思想是将一个大问题分解为一个或多个相同类型的小问题,然后解决每个小问题,并将它们的解决方案组合起来得到原始问题的解决方案。递归方法必须有一个基本情况,以便在基本情况下终止递归调用。

在Java中,递归可以用于解决各种问题,例如计算阶乘、斐波那契数列、遍历树等。但需要注意的是,递归可能会导致栈溢出的错误,因为每次递归调用都会将方法的调用信息存储在栈中。因此,递归需要谨慎使用,并确保有适当的终止条件。

示例

求 N!

起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件.

递归公式: 求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)!

代码示例

递归求 N 的阶乘

class Main{
    public static void main(String[] args) {
        int n = 5;
        int ret = factor(n);
        System.out.println("ret = " + ret);
    }
    public static int factor(int n) {
        if (n == 1) {
            return 1;
        }
        return n * factor(n - 1); // factor 调用函数自身
    }
}

在这里插入图片描述

二、递归执行过程分析

递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 “方法的执行过程”, 尤其是 “方法执行结束之后, 回到调用位置继续往下执行”.

代码示例

递归求 N 的阶乘, 加上日志版本

class Main{
    public static void main(String[] args) {
        int n = 5;
        int ret = factor(n);
        System.out.println("ret = " + ret);
    }
    public static int factor(int n) {
        System.out.println("函数开始, n = " + n);
        if (n == 1) {
            System.out.println("函数结束, n = 1 ret = 1");
            return 1;
        }
        int ret = n * factor(n - 1);
        System.out.println("函数结束, n = " + n + " ret = " + ret);
        return ret;
    }
}

在这里插入图片描述

执行过程图

在这里插入图片描述
程序按照序号中标识的 (1) -> (8) 的顺序执行.

关于 “调用栈”

方法调用的时候, 会有一个 “栈” 这样的内存空间描述当前的调用关系. 称为调用栈.

每一次的方法调用就称为一个 “栈帧”, 每个栈帧中包含了这次调用的参数是哪些, 返回到哪里继续执行等信息.

三、递归练习

代码示例

按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)

public static void print(int num) {
        if (num > 9) {
            print(num / 10);
        }
        System.out.println(num % 10);
    }

递归求 1 + 2 + 3 + … + 10

public static int sum(int num) {
        if (num == 1) {
            return 1;
        }
        return num + sum(num - 1);
    }

写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19

public static int sum(int num) {
        if (num < 10) {
            return num;
        }
        return num % 10 + sum(num / 10);
    }

求斐波那契数列的第 N 项

斐波那契数列介绍

斐波那契数列是一个数学上的数列,其形式为 1, 1, 2, 3, 5, 8, 13, 21, 34, …。数列中的每个数字都是前面两个数字之和。也就是说,第三个数字是前两个数字之和,第四个数字是前两个数字之和,以此类推。

斐波那契数列最早由13世纪的意大利数学家斐波那契(Fibonacci)发现和研究,他在其著作《算盘书》中介绍了这个数列,并将其应用于兔子繁殖的模型中。

斐波那契数列在数学中有着重要的应用和性质。它在自然界中也有许多出现的现象,例如植物的叶子排列、螺旋壳的形状等都可以用斐波那契数列来描述。

斐波那契数列也有一些有趣的特性,例如当数列中的数字趋近无穷时,相邻两个数字的比值会趋近于黄金分割比例0.618。这个黄金分割比例在艺术和设计中也有广泛的应用。

斐波那契数列除了以上的介绍,还有其他的许多性质和应用,它在数学中被广泛研究和讨论。

public static int fib(int n) {
        if (n == 1 || n == 2) {
            return 1;
        }
        return fib(n - 1) + fib(n - 2);
    }

当我们求 fib(40) 的时候发现, 程序执行速度极慢. 原因是进行了大量的重复运算.

class Main {
    public static int count = 0; // 这个是类的成员变量. 后面会详细介绍到.

    public static void main(String[] args) {
        System.out.println(fib(40));
        System.out.println(count);
    }

    public static int fib(int n) {
        if (n == 1 || n == 2) {
            return 1;
        }
        if (n == 3) {
            count++;
        }
        return fib(n - 1) + fib(n - 2);
    }
}

在这里插入图片描述
可以使用循环的方式来求斐波那契数列问题, 避免出现冗余运算.

class Main {
    public static int count = 0; // 这个是类的成员变量. 后面会详细介绍到.

    public static void main(String[] args) {
        System.out.println(fib(40));
        System.out.println(count);
    }

    public static int fib(int n) {
        int last2 = 1;
        int last1 = 1;
        int cur = 0;
        for (int i = 3; i <= n; i++) {
            cur = last1 + last2;
            last2 = last1;
            last1 = cur;
        }
        return cur;
    }

}

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/635630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全网首发UNIAPP功能多的iapp后台源码

全网首发UNIAPP功能多的iapp后台源码&#xff0c;众所周知UN Dev Assist 后台是一款既不免费又不好用的后台今天直接分享。 搭建教程在里面了&#xff0c;自己查看。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89291994 更多资源下载&#xff1a;…

PDF Candy Desktop v2.89软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; PDF Candy Desktop v2.89是一款多功能且操作简便的PDF转换工具。该软件不仅功能强大&#xff0c;还能帮助用户将PDF文件转换为多种格式的文档&#x…

dubbo复习:(4) 和springboot 整合时,客户端负载均衡的配置

需要在DubboReference注解指定loadbalance属性。示例如下&#xff1a; package cn.edu.tju.service;import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Ser…

深度学习 | 复杂注意力神经网络 —— 大模型

前面讲解了注意力神经网络 一、BERT模型 1、什么是BERT 它是由谷歌在2018年提出的 双向Transformer 编码器模型。 Bidirectional Encoder Representations from Transformers. 主要使用了Transformer的编码器 Transformer 编码器堆叠&#xff1b; 预训练 精调两步结构。 BERT…

Ubuntu 整编 AOSP

文章目录 前言1 准备一台Ubuntu系统电脑2 安装依赖工具3 安装 repo4 下载 AOSP 源码5 整编AOSP6 运行 前言 作为Android应用层开发多年, 一直不了解 Framework和Android系统的运行原理真的说不过去。希望本篇博客可以带你构建自己的Android系统&#xff0c;打开通向 Framework…

【算法】【二叉树,DFS,哈希集合,分类讨论】力扣1110. 删点成林

1110. 删点成林 文章目录 【算法】力扣【二叉树&#xff0c;DFS&#xff0c;哈希集合&#xff0c;分类讨论】1110. 删点成林题目描述示例 1&#xff1a;示例 2&#xff1a; 输入输出示例解释思路解析核心思想算法步骤复杂度分析 代码实现总结 【算法】力扣【二叉树&#xff0c…

电脑卸载linux安装windows后每次开机都出现grub

原因分析 这是因为电脑硬盘中还存在linux系统的引导程序&#xff0c;并且启动顺序还在windows之前&#xff0c;有时候通过bios根本找不到它的存在&#xff0c;以至于每次windows开机出现grub之后都要输入exit退出linux的引导之后才能使得电脑进入windows&#xff0c;这个有时会…

跟着Kimi学习结构化提示词:19套内置提示词都在这里了!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

计算机毕业设计 | springboot药品库存追踪与管理系统 药店管理(附源码)

1&#xff0c;绪论 1.1 背景调研 如今药品调价频繁&#xff0c;且品种繁多&#xff0c;增加了药品销售定价的难度。药品来货验收登记中的审查有效期环节容易出错&#xff0c;错收过期或有效期不足的药品。 手工模式下的药品库存难以及时掌握&#xff0c;虽然采取了每日进行缺…

数据库小项目——叮叮移动业务大厅(三层架构+MySQL数据库)

源码已上传至资源 该项目主要使用技术为MySQL数据库&#xff0c;其中也包含了一些对于文件的写入和读取操作。项目结构采用三层架构&#xff0c;后端的业务逻辑清晰明了。 1.项目结构 项目采用控制台版&#xff0c;前端业务在java包下&#xff0c;每个业务单独成块。若想要GUI…

Day05-Grafana的基本应用与配置

Day05-Grafana的基本应用与配置 1. Grafana概述2. Grafana实战2.1 环境准备2.2 使用流程1&#xff09;部署grafana 9.3.62&#xff09;web页面访问3&#xff09;配置zbx插件4&#xff09;配置grafana的数据源5&#xff09;web: Grafana web页面添加与配置图形dashboard,仪表盘6…

linux命令中arj使用

arj 用于创建和管理.arj压缩包 补充说明 arj命令 是 .arj 格式的压缩文件的管理器&#xff0c;用于创建和管理 .arj 压缩包。 语法 arj(参数)参数 操作指令&#xff1a;对 .arj 压缩包执行的操作指令&#xff1b;压缩包名称&#xff1a;指定要操作的arj压缩包名称。 更多…

【投稿资讯】区块链会议CCF A -- SP 2025 截止6.6、11.14 附录用率

会议名称&#xff1a;46th IEEE Symposium on Security and Privacy( S&P&#xff09; CCF等级&#xff1a;CCF A类学术会议 类别&#xff1a;网络与信息安全 录用率&#xff1a;2023年 195/1147&#xff0c;2024年录用了17篇和区块链相关的论文 Topics of interest inc…

C语言 | Leetcode C语言题解之第108题将有序数组转换为二叉搜索树

题目&#xff1a; 题解&#xff1a; struct TreeNode* helper(int* nums, int left, int right) {if (left > right) {return NULL;}// 选择任意一个中间位置数字作为根节点int mid (left right rand() % 2) / 2;struct TreeNode* root (struct TreeNode*)malloc(sizeo…

uview1.0 u-form表单回显校验不通过

提交到后端的数据&#xff0c;回显后不做任何修改无法通过表单校验 原因&#xff0c;u-form表单校验的类型默认为string&#xff0c;但是后端返回的是integer类型&#xff0c;导致无法通过校验 解决&#xff0c;既然后端返回的是整数形&#xff0c;那么我们就将校验规则的type…

[机缘参悟-185] - 《道家-水木然人间清醒1》读书笔记 - 真相本质 -8- 认知觉醒 - 逻辑谬误、认知偏差:幸存者偏差

目录 前言&#xff1a; 一、幸存者偏差 二、幸存者偏差在现实中的应用 第一个故事&#xff1a; 第二个故事&#xff1a; 三、生活中的幸存者偏差 四、迷恋成功者经验的原因&#xff1a;鸡汤、幻想、传奇、希望 备注&#xff1a; 前言&#xff1a; 幸存者偏差&#xff0…

Backend - 数据分析 matplotlib

目录 一、作用 二、安装环境 &#xff08;一&#xff09;虚拟环境终端 &#xff08;二&#xff09;代码导入库 &#xff08;三&#xff09;设置中文 1. 使用window自带&#xff08;推荐&#xff09; 2. 下载字体 三、应用 &#xff08;一&#xff09;基础知识 1. plt…

Spring Cloud Alibaba-07-RocketMQ消息驱动

Lison <dreamlison163.com>, v1.0.0, 2024.4.20 Spring Cloud Alibaba-07-RocketMQ消息驱动 文章目录 Spring Cloud Alibaba-07-RocketMQ消息驱动MQ简介MQ的应用场景常见的MQ产品RocketeMQ的架构及概念 RocketMQ入门RocketMQ环境搭建 SpringBoot 集成 RocketMQ MQ简介 …

汐鹤Key码查询,网站授权系统源码

汐鹤Key码查询和网站授权系统源码主要用于特殊虚拟物品销售商家。 下 载 地 址 &#xff1a; runruncode.com/php/19770.html 附带插件功能&#xff08;网站授权&#xff09;&#xff0c;但目前开发内容较少&#xff0c;请谅解&#xff01;同时&#xff0c;代码优化空间很大…

【论文极速读】 LLava: 指令跟随的多模态大语言模型

【论文极速读】 LLava: 指令跟随的多模态大语言模型 FesianXu 20240331 at Tencent WeChat Search Team 前言 如何将已预训练好的大规模语言模型&#xff08;LLM&#xff09;和多模态模型&#xff08;如CLIP&#xff09;进行融合&#xff0c;形成一个多模态大语言模型&#xf…