Java 之 递归
一、概述
递归:指在当前方法内调用自己的现象。
递归的分类:
- 递归分为两种,直接递归和间接递归
- 直接递归称为方法自身调用自己
- 间接递归可以 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 之 递归的更多相关文章
- 关于java的递归写法,经典的Fibonacci数的问题
经典的Fibonacci数的问题 主要想展示一下迭代与递归,以及尾递归的三种写法,以及他们各自的时间性能. public class Fibonacci { /*迭代*/ public static ...
- java 中递归的实现 以及利用递归方法实现汉诺塔
今天说下java语言中比较常见的一种方法,递归方法. 递归的定义 简单来说递归的方法就是"自己调用自己",通过递归方法往往可以将一个大问题简单化,最终压缩到一个易于处理的程度.对于 ...
- Java 之递归删除目录
Java 之递归删除目录 一.思想 必须从最里层的文件开始删除,使用递归删除. 二.源代码:RecursiveDeleteDirectory.java package cn.com.zfc.day01 ...
- Java 之递归遍历目录
Java 之递归遍历目录 一.内容 输出指定目录(文件夹)下的所有文件(包括目录)的绝对路径 二.源代码:RecursiveListDirectory.java package cn.com.zfc. ...
- Java实现递归将嵌套Map里的字段名由驼峰转为下划线
摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...
- Java面向对象-递归
Java面向对象-递归 递归,就是程序调用自身,我们讲的是方法递归调用,也就是在方法里自己调用自己: 我们给出一个案例,求阶乘 1*2*3*...*(n-1)*n 我们用非递归和递归方式分别实现下, ...
- java方法---递归
java方法递归 1.什么是递归 就是自己调用自己: 2.递归结构的两个部分 递归头:什么时候不调用自身方法.如果仅有头,将陷入死循环.递归体:什么时候需要调用自身方法.
- java 使用递归获取指定文件路径目录,删除指定的文件后缀(可扩展,根据具体需要的删除的后缀进行配置)~~
在工作开发过程中,每次用SVN提交代码全选择的时候,发现会产生很多不需要的文件后缀垃圾文件,感觉挺烦人的,一个一个删太麻烦了,如果产生多种后缀文件时,那删起来多费劲,是吧?想想,就写了一段程序通过递归 ...
- Java API —— 递归
1.方法定义中调用方法本身的现象 2.递归注意实现 1) 要有出口,否则就是死递归 2) 次数不能太多,否则就内存溢出 3) 构造方法不能递归使用 3. ...
- Java使用递归找出某目录下的所有子目录以及子文件
/* 使用递归找出某目录("C:\\JavaProducts")下的所有子目录以及子文件 */ import java.util.*; import java.io.*; publ ...
随机推荐
- python中修改列表元素的方法
一.在for循环中直接更改列表中元素的值不会起作用: 如: l = list(range(10)[::2]) print (l) for n in l: n = 0 print (l) 运行结果: [ ...
- 实现不同的项目,用不同的git 账号提交
可以全局配置一个git 账户名和密码,然后在具体项目里单独配置一个账户名和密码 例如: git config --global user.name "winyh" git conf ...
- laravel redis sentinel 和 redis cluster 配置
laravel redis sentinel配置: 'redis' => [ 'cluster' => false, 'options' => [ 'replication' =&g ...
- [转]Xmind 8 pro 软件破解版
链接地址:https://blog.csdn.net/qq_16093323/article/details/80967867 作者博客:http://www.carrotchou.blog/
- express url跳转(重定向)的实现:res.location() res.redirect()
Express 是一个基于Node.js 实现的web框架,其响应HTTP请求的response对象中有两个响应url跳转方法res.location() res.redirect(),可以实现301 ...
- CentOS6安装MySQL开启远程登录
Centos6安装MySQL 检测下系统有没有自带的mysql:yum list installed | grep mysql 如果已经有的话执行命令 yum -y remove mysql-libs ...
- Rsync同步部署web服务端配置
Rsync同步部署web服务端配置 1,参数详解: -v, --verbose 详细模式输出. -q, --quiet 精简输出模式. -c, --checksum 打开校验开关,强制对文件传输进行校 ...
- vue之$event获取当前元素的节点
<p @click = “clickfun($event)”>点击</p> methods: { clickfun(e) { // e.target 是你当前点击的元素 // ...
- MySQL引擎类型(三)
InnoDB: 1)经常更新的表,适合处理多重并发的更新请求. 2)支持事务. 3)可以从灾难中恢复(通过bin-log日志等). 4)外键约束.只有他支持外键. 5)支持自动增加列属性auto_in ...
- 十分钟快速入门 Python,看完即会,不用收藏!
本文以 Eric Matthes 的<Python编程:从入门到实践>为基础,以有一定其他语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章. ...