Java-递归思想
1 .递归:方法定义中调用方法本身的现象
误区
- StringBuffer的对象.append().append().append() 这个不叫方法的递归,这个现象叫做方法的链式调用 Math.min(Min(a,b),c) 这个现象叫做方法嵌套调用,也不叫递归
1、从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是: 1
从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是: 2
从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是: 3
从前有座山,山里有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的故事内容是: 4
....
以下情况,故事不在衍生:庙倒了,老和尚圆寂了。。
2、学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
学习大数据--高薪就业--挣钱--娶媳妇--生娃--挣钱学习大数据:
....
娶不到媳妇,生不了娃。
递归注意事项:
- 1、递归一定要有一个出口,结束条件,否则就是死递归
- 2、递归的次数不能太多,否则就会造成栈内存溢出
- 3、构造方法不能初始化
public class DiGuiDemo1 {
// DiGuiDemo1(){
// DiGuiDemo1();
// }
public static void show(int i){
//要使用递归,必须要给出条件,否则就会无线循环下去。
if(i < 0){
System.out.println("结束循环!");
}else{
System.out.println(i);
//递归调用本身, 先执行 --i 之后的结果在丢到 show 方法中
show(--i);
}
}
public static void main(String[] args) {
//调用方法
DiGuiDemo1.show(10);
}
}
需求:求出 5 的阶乘
package com.shujia.wyh.day23;
/*
需求:求出5的阶乘:
5! = 5*4*3*2*1 = 120
= 5*4!
= 5*4*3!
= 5*4*3*2!
= 5*4*3*2*1!
*/
public class DiGuiDemo2 {
public static void main(String[] args) {
//在学习递归之前解决该问题的方式:
// System.out.println(5*4*3*2*1);
int result = 1;
for (int i = 2; i <= 5; i++) {
result = result * i;
}
System.out.println("5的阶乘为:" + result);
System.out.println("===================================");
//使用递归实现
int i = jieCheng(5);
System.out.println("5的阶乘为:" + i);
}
/*
定义递归方法实现求阶乘
1、结束条件:
if(i==1){return 1}
2、递归的规律:
if(i!=1){
return i*jieCheng(i-1);
}
*/
public static int jieCheng(int i) { // 5
if (i == 1) {
return 1;
} else {
//5 * jieCheng(4)
//5 * 4 * jieCheng(3)
//5 * 4 * 3 * jieCheng(2)
//5 * 4 * 3 * 2 * jieCheng(1)
return i * jieCheng(i - 1);
}
}
}
不死神兔问题:
package com.shujia.wyh.day23;
/*
兔子问题(斐波那契数列) 不死神兔
有一对兔子,从出生第三个月开始,每个月都生一对兔子
小兔子长到三个月后又每个月生一对兔子,假设这些兔子都不会死
问:第20个月,有多少对兔子?
寻找规律:
月 对数
1 1
2 1
3 2
4 3
5 5
6 8
7 13
...
由此可见,兔子的对数数量:
1,1,2,3,5,8,13,21,34....
发现的规律是:
1、从第三项开始,每一项都是前两项之和
2、说明每一项的前两项数据是已知的
如何实现:
1、使用数组实现
2、基本变量实现
3、递归实现
*/
public class DiGuiDemo3 {
public static void main(String[] args) {
//使用数组实现
int[] arr = new int[20];
arr[0] = 1;
arr[1] = 1;
// arr[2] = arr[0]+arr[1];
// arr[3] = arr[1]+arr[2];
// arr[4] = arr[2]+arr[3];
// //...
// arr[19] = arr[17]+arr[18];
//使用循环改进
for (int i = 2; i < arr.length; i++) {
arr[i] = arr[i - 2] + arr[i - 1];
}
System.out.println("第20个月的时候,兔子对数为:" + arr[19]);
System.out.println("====================================");
//基本变量实现
//定义两个变量表示相邻的两项
//第1个相邻的数据: a=1,b=1;
//第2个相邻的数据: a=1,b=2;
//第3个相邻的数据: a=2,b=3;
//第4个相邻的数据: a=3,b=5;
//第5个相邻的数据: a=5,b=8;
//第6个相邻的数据: a=8,b=13;
//...
//规律:
//下一次的相邻数据a是上一次相邻数据b的值,下一次相邻数据b是上一次a+b的值
int a = 1;
int b = 1;
for (int i = 0; i < 18; i++) {
//定义一个临时变量,保存上一次的a的值
int temp = a;
a = b;
b = temp + b;
}
System.out.println("第20个月的时候,兔子对数为:" + b);
System.out.println("=======================================");
//使用递归实现
int result = fibonacci(20);
System.out.println("第20个月的时候,兔子对数为:" + result);
}
/*
递归实现:
1、结束条件是什么?
当月份是1或者2的时候,return 1;
2、递归的逻辑是:
从第三个月到第20个月,每一个月是前两个月之和。
*/
public static int fibonacci(int month) { // 5
if (month == 1 || month == 2) {
return 1;
} else {
//fibonacci(4) + fibonacci(3)
//fibonacci(3) + fibonacci(2) + fibonacci(2) + fibonacci(1)
//fibonacci(2) + fibonacci(1) + fibonacci(2) + fibonacci(2) + fibonacci(1)
//1 + 1 + 1 + 1 + 1 = 5
return fibonacci(month - 1) + fibonacci(month - 2);
}
}
}
遍历递归文件名
package com.shujia.wyh.day23;
import java.io.File;
/*
递归遍历D:\IdeaProjects\bigdata17\src\com\shujia\wyh目录下指定后缀名.jpg结尾的文件名称
*/
public class DiGuiDemo4 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects\\bigdata17\\src\\com\\shujia\\wyh");
//定义一个递归方法实现
getJpgFile(file);
}
public static void getJpgFile(File file) {
//获取该目录下所有文件和文件夹组成的File对象数组
File[] files = file.listFiles();
//遍历数组得到每一个File对象
for (File f : files) {
//判断该File对象是否是一个文件夹
if(f.isDirectory()){
getJpgFile(f);
}else {
//判断该文件的名称是否以.jpg后缀
if(f.getName().endsWith(".png")){
//是,就输出
System.out.println(f);
}
}
}
}
}
递归删除带内容的目录
import java.io.File;
import java.io.FileFilter;
/*
递归删除带内容的目录
*/
public class DiGuiDemo5 {
public static void main(String[] args) {
// File file = new File("D:\\aaaa");
// File[] files = file.listFiles();
//// System.out.println(files);
// System.out.println(files.length);
File file = new File("D:\\aaaa");
deleteFile(file);
}
public static void deleteFile(File file) {
//获取该目录下所有的文件和文件夹组成的File对象数组
File[] files = file.listFiles();
//判断这个数组是不是空,如果是空的,就直接删除
if (files.length != 0) {
//遍历数组
for(File f : files){
//判断是否是文件夹
if(f.isDirectory()){
deleteFile(f);
}else {
//不是文件夹的时候,可以直接删除
System.out.println(f.getName() + ":" + f.delete());
}
}
System.out.println(file.getName() + ":" + file.delete());
} else {
System.out.println(file.getName() + ":" + file.delete());
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构