一、概述

  递归:指在当前方法内调用自己的现象。

  递归的分类

    •  递归分为两种,直接递归间接递归
    • 直接递归称为方法自身调用自己
    • 间接递归可以 A 方法调用 B 方法,B 方法调用 C 方法,C 方法调用 A 方法。

  注意

    •  递归一定要有条件限制,保证递归能够停止下来,否则会发生栈内存溢出。
    • 在递归中虽然有限定条件,但是递归次数不能太多,苟泽也会发生栈内容溢出。
    • 构造方法,进制递归。

  递归导致栈内存溢出的原理:

  

二、案例

  1、递归累加求和

    计算 1~ n 的和,n 的累加 = n + (n+1) 的累和,可以把累和的操作定义成一个方法,递归调用。

    实现:

 public class Demo {
public static void main(String[] args) {
//计算1~num的和,使用递归完成
int num = 5;
// 调用求和的方法
int sum = getSum(num);
// 输出结果
System.out.println(sum);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getSum(int num) {
/*
num为1时,方法返回1,
相当于是方法的出口,num总有是1的情况
*/
if(num == 1){
return 1;
}
/*
num不为1时,方法返回 num +(num‐1)的累和
递归调用getSum方法
*/
return num + getSum(num‐1);
}
}

  代码执行图解

   注意:递归一定要有条件限定,保证递归能够停止下来,次数不要太多,否则会发生栈内存溢出。

  2、递归求阶乘

    阶乘:所有小于及等于该数的正整数的积。

    分析:n! = n * (n-1);

    实现:

 public class DiGuiDemo {
//计算n的阶乘,使用递归完成
public static void main(String[] args) {
int n = 3;
// 调用求阶乘的方法
int value = getValue(n);
// 输出结果
System.out.println("阶乘为:"+ value);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getValue(int n) {
// 1的阶乘为1
if (n == 1) {
return 1;
}
/*
n不为1时,方法返回 n! = n*(n‐1)!
递归调用getValue方法
*/
return n * getValue(n ‐ 1);
}
}

  3、递归求年龄

    问题:第一个人10,第2个比第1个人大2岁,以此类推,请用递归方式计算出第8个人多大?

    实现:

   public int getAge(int n){
/*
* 第一个人10,n=1, 结果10
* 第二个人12,n=2, 结果10 + 2 getAge(1) + 2
* 第三个人14,n=3, 结果10 + 2 + 2 getAge(2) + 2
*
* 第n个人?,n=?, 结果10 + 2 + 2 ...+ ? getAge(n-1) + 2
*/
if(n==1){
return 10;
}else{
return getAge(n-1) + 2;
}
}

  4、递归—爬台阶问题

    问题:有n步台阶,一次只能上1步或2步,共有多少种走法?

    实现:

   public long sum(int n){
/*
* n==1 1
* n==2 2
* n==3 最后一步 要么从第1级跨2步,要么从第2级跨1步 把走到第1级的走法 + 走到第2级的走法 sum(1) + sum(2)
* n==4 最后一步 要么从第2级跨2步,要么从第3级跨1步 把走到第2级的走法 + 走到第3级的走法 sum(2) + sum(3)
* n==5 最后一步 要么从第3级跨2步,要么从第4级跨1步 把走到第3级的走法 + 走到第4级的走法 sum(3) + sum(4)
*
* n=? 最后一步 要么从第n-2级跨2步,要么从第n-1级跨1步 把走到第n-2级的走法 + 走到第n-1级的走法 sum(n-2) + sum(n-1)
*/
if(n==1 || n==2){
return n;
}else{
return sum(n-1) + sum(n-2);
}
}

三、递归与文件操作

  1、递归打印多级目录

    分析:多级目录的打印,就是当目录的嵌套。遍历之前,无从知道到底有多少级目录,所以我们还是要使用递归实现。

    实现1:

 public class DiGuiDemo {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
}
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
/*
判断:
当是文件时,打印绝对路径.
当是目录时,继续调用打印目录的方法,形成递归调用.
*/
for (File file : files) {
// 判断
if (file.isFile()) {
// 是文件,输出文件绝对路径
System.out.println("文件名:"+ file.getAbsolutePath());
} else {
// 是目录,输出目录绝对路径
System.out.println("目录:"+file.getAbsolutePath());
// 继续遍历,调用printDir,形成递归
printDir(file);
}
}
  }
}

    实现2:

    //listAllSub()方法的功能是列出一个文件或一个目录及它的下一级
public void listAllSub(File dir){
if(dir.isDirectory()){
File[] listFiles = dir.listFiles();
for (File sub : listFiles) {//sub可能是一个文件,也可能是一个文件夹
listAllSub(sub);//递归:自己调用自己
}
}
System.out.println(dir);
}

  2、递归求文件或目录大小

    实现:

   public long getLength(File dir){
if (dir != null && dir.isDirectory()) {
File[] listFiles = dir.listFiles();
if(listFiles!=null){
long sum = 0;
for (File sub : listFiles) {
sum += getLength(sub);
}
return sum;
}
}else if(dir != null && dir.isFile()){
return dir.length();
}
return 0;
}

  3、递归删除文件

   实现:

   public void deleteDir(File file){
//如果是文件夹,先把它的下一级删除
if(file.isDirectory()){
File[] listFiles = file.listFiles();
//经过这个foreach循环,可以把file的所有的下一级删除
for (File sub : listFiles) {
deleteDir(sub);
}
} //文件夹就变成了空文件夹,就可以直接删
//如果是文件也可以直接删除
file.delete();
}

Java 之 递归的更多相关文章

  1. 关于java的递归写法,经典的Fibonacci数的问题

    经典的Fibonacci数的问题 主要想展示一下迭代与递归,以及尾递归的三种写法,以及他们各自的时间性能. public class Fibonacci { /*迭代*/ public static ...

  2. java 中递归的实现 以及利用递归方法实现汉诺塔

    今天说下java语言中比较常见的一种方法,递归方法. 递归的定义 简单来说递归的方法就是"自己调用自己",通过递归方法往往可以将一个大问题简单化,最终压缩到一个易于处理的程度.对于 ...

  3. Java 之递归删除目录

    Java 之递归删除目录 一.思想 必须从最里层的文件开始删除,使用递归删除. 二.源代码:RecursiveDeleteDirectory.java package cn.com.zfc.day01 ...

  4. Java 之递归遍历目录

    Java 之递归遍历目录 一.内容 输出指定目录(文件夹)下的所有文件(包括目录)的绝对路径 二.源代码:RecursiveListDirectory.java package cn.com.zfc. ...

  5. Java实现递归将嵌套Map里的字段名由驼峰转为下划线

    摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...

  6. Java面向对象-递归

    Java面向对象-递归 递归,就是程序调用自身,我们讲的是方法递归调用,也就是在方法里自己调用自己: 我们给出一个案例,求阶乘  1*2*3*...*(n-1)*n 我们用非递归和递归方式分别实现下, ...

  7. java方法---递归

    java方法递归 1.什么是递归 就是自己调用自己: 2.递归结构的两个部分 递归头:什么时候不调用自身方法.如果仅有头,将陷入死循环.递归体:什么时候需要调用自身方法.

  8. java 使用递归获取指定文件路径目录,删除指定的文件后缀(可扩展,根据具体需要的删除的后缀进行配置)~~

    在工作开发过程中,每次用SVN提交代码全选择的时候,发现会产生很多不需要的文件后缀垃圾文件,感觉挺烦人的,一个一个删太麻烦了,如果产生多种后缀文件时,那删起来多费劲,是吧?想想,就写了一段程序通过递归 ...

  9. Java API —— 递归

    1.方法定义中调用方法本身的现象 2.递归注意实现         1) 要有出口,否则就是死递归         2) 次数不能太多,否则就内存溢出         3) 构造方法不能递归使用 3. ...

  10. Java使用递归找出某目录下的所有子目录以及子文件

    /* 使用递归找出某目录("C:\\JavaProducts")下的所有子目录以及子文件 */ import java.util.*; import java.io.*; publ ...

随机推荐

  1. python中修改列表元素的方法

    一.在for循环中直接更改列表中元素的值不会起作用: 如: l = list(range(10)[::2]) print (l) for n in l: n = 0 print (l) 运行结果: [ ...

  2. 实现不同的项目,用不同的git 账号提交

    可以全局配置一个git 账户名和密码,然后在具体项目里单独配置一个账户名和密码 例如: git config --global user.name "winyh" git conf ...

  3. laravel redis sentinel 和 redis cluster 配置

    laravel redis sentinel配置: 'redis' => [ 'cluster' => false, 'options' => [ 'replication' =&g ...

  4. [转]Xmind 8 pro 软件破解版

    链接地址:https://blog.csdn.net/qq_16093323/article/details/80967867 作者博客:http://www.carrotchou.blog/

  5. express url跳转(重定向)的实现:res.location() res.redirect()

    Express 是一个基于Node.js 实现的web框架,其响应HTTP请求的response对象中有两个响应url跳转方法res.location() res.redirect(),可以实现301 ...

  6. CentOS6安装MySQL开启远程登录

    Centos6安装MySQL 检测下系统有没有自带的mysql:yum list installed | grep mysql 如果已经有的话执行命令 yum -y remove mysql-libs ...

  7. Rsync同步部署web服务端配置

    Rsync同步部署web服务端配置 1,参数详解: -v, --verbose 详细模式输出. -q, --quiet 精简输出模式. -c, --checksum 打开校验开关,强制对文件传输进行校 ...

  8. vue之$event获取当前元素的节点

    <p @click = “clickfun($event)”>点击</p> methods: { clickfun(e) { // e.target 是你当前点击的元素 // ...

  9. MySQL引擎类型(三)

    InnoDB: 1)经常更新的表,适合处理多重并发的更新请求. 2)支持事务. 3)可以从灾难中恢复(通过bin-log日志等). 4)外键约束.只有他支持外键. 5)支持自动增加列属性auto_in ...

  10. 十分钟快速入门 Python,看完即会,不用收藏!

    本文以 Eric Matthes 的<Python编程:从入门到实践>为基础,以有一定其他语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章. ...