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 ...
随机推荐
- nginx通过robots.txt禁止所有蜘蛛访问(禁止搜索引擎收录)
在server {} 块中添加下面的配置 location =/robots.txt { default_type text/html; add_header Content-Type "t ...
- php 验证rsa公钥和私钥是否正确
<?php /** * RSA加密 * * @param string $data 待加密数据 * @param string $publicKey 公钥 * @return string|fa ...
- ABAP DMEO 通过工单号读取内部对象号
*&---------------------------------------------------------------------* *& Report YDEMO_013 ...
- Nginx配置自定义的403页面
1.开启nginx的状态码,虚拟主机配置中加入下边一段 location /nginx_status{ stub_status on; access_log off; } 或着在nginx的http模 ...
- 正则表达式\s空格,\d数字,量词+*?测试
之前的博文中: 有正则表达式的\b.i.\g,本文再测试了空格数字和量词的匹配.这篇只测试匹配,不替换或其他处理.\s空格:测试实际写空格也能识别,但是不利于看出空了几个空格,可以用\s代表空格.\d ...
- AWS 监控服务(六)
AWS CloudWatch 概念 基于确定的内容监控基础设施组件 基于指定的指标发送通知并触发各种操作 分布式统计数据和收集系统,用于收集并跟踪指标 默认情况下,在管理程序级别无缝收集指标,如CPU ...
- SQL命令如何分发到集群的各节点
有些数据库集群的规模是很大的,有上百个节点,那么维护SQL命令如何快速分发给各个节点,例如:要加个字段,逐个节点操作那是十分低效,枯燥的. TreeSoft增加了[SQL分发]功能,简单配置,可以快速 ...
- 说说Spring XML的头
部分内容截取自(http://blog.csdn.net/zhch152/article/details/8191377,http://iswift.iteye.com/blog/1657537) 在 ...
- LeetCode 102. 二叉树的层次遍历(Binary Tree Level Order Traversal) 8
102. 二叉树的层次遍历 102. Binary Tree Level Order Traversal 题目描述 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 每 ...
- myeclipse 相关问题
[如何设置 Tab 键为四个空格] https://blog.csdn.net/QQ826688096/article/details/90543252