什么是方法递归?
- 方法直接调用自己或者间接调用自己的形式称为方法递归( recursion)。
- 递归做为一种算法在程序设计语言中广泛应用。
递归的形式
- 直接递归:方法自己调用自己。
- 间接递归:方法调用其他方法,其他方法又回调方法自己。
方法递归存在的问题?
- 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象。
递归计算n的阶乘
public class RecursionDemo {
public static void main(String[] args) {
System.out.println("5的阶乘 :"+f(5)); //5的阶乘 :120
}
private static int f(int n) {
if(n == 1){
return 1;
}else{
return n*f(n-1);
}
}
}
递归解决问题的思路:
- 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归算法三要素大体可以总结为:
- 递归的公式
- 递归的终结点
- 递归的方向必须走向终结点
递归的常见案例
1、计算1-n的和
public class RecursionDemo2 {
public static void main(String[] args) {
System.out.println(sum(5));//15
}
private static int sum(int n) {
if(n==1){
return 1;
}else{
return n + sum(n-1);
}
}
}
2、猴子吃桃问题
猴子第一天摘下若干桃子,当即吃了一半,觉得好不过瘾,于是又多吃了一个,第二天又吃了前天剩余桃子数量的一半,觉得好不过瘾,于是又多吃了一个,以后每天都是吃前天剩余桃子数量的一半,觉得好不过瘾,又多吃了一个等到第10天的时候发现桃子只有1个了。需求:请问猴子第一天摘了多少个桃子?
/*
推导
第一天的桃子 f(x)
第二天的桃子 f(x+1) = f(x) - f(x)/2 -1
2f(x+1) = 2f(x) - f(x) -2
2f(x+1) + 2 = f(x)
得出公式:f(x) = 2f(x+1) + 2
*/
public class RecursionDemo3 {
public static void main(String[] args) {
System.out.println(f(1));//1534
}
private static int f(int n) {
if(n==10){
return 1;
}else{
return 2 * f(n + 1) +2;
}
}
}
3、文件搜索、从D:盘中,搜索出某个文件名称并输出绝对路径。
分析:
①先定位出的应该是一级文件对象
②遍历全部一级文件对象,判断是否是文件
③如果是文件,判断是否是自己想要的
④如果是文件夹,需要继续递归进去重复上述过程
import java.io.File;
public class RecursionDemo4 {
public static void main(String[] args) {
searchFile(new File("D:/"),"ApiPost_Setup_5.1.1_x64.exe");
}
/**
* 搜索某个目录下的全部文件,找到我们想要的
* @param dir 被搜索的原目录
* @param fileName 被搜索的文件名
*/
public static void searchFile(File dir , String fileName){
if(dir != null && dir.isDirectory()){
File[] files = dir.listFiles();
if(files != null && files.length > 0){
for (File file : files) {
if(file.isFile()){
if(file.getName().contains(fileName)){
System.out.println("找到了:" + file.getAbsolutePath());
}
}else{
searchFile(file,fileName);
}
}
}
}else{
System.out.println("当前搜索的位置不是文件夹");
}
}
}
4、啤酒问题
需求:啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶,请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。答案:15瓶3盖子1瓶子
public class RecursionDemo5 {
public static int totalNumber; //总数量
public static int lastBottleNumber; //记录每次剩余的瓶子个数
public static int lastCoverNumber; //记录每次剩余的盖子个数
public static void main(String[] args) {
buy(10);
System.out.println("总数:" + totalNumber);
System.out.println("剩余盖子数:" + lastCoverNumber);
System.out.println("剩余瓶子数:" + lastBottleNumber);
}
public static void buy(int money){
//看看可以立马买多少瓶
int buyNum = money / 2;
totalNumber += buyNum;
//把盖子和瓶子换算成钱
//统计本轮总的盖子数和瓶子数
int coverNum = lastCoverNumber + buyNum;
int bottleNum = lastBottleNumber +buyNum;
//统计可以换算的钱
int allMoney = 0;
if(coverNum >= 4){
allMoney += (coverNum / 4) * 2 ;
}
lastCoverNumber = coverNum % 4;
if(bottleNum >= 2){
allMoney += (bottleNum / 2) * 2;
}
lastBottleNumber = bottleNum % 2;
if(allMoney >= 2){
buy(allMoney);
}
}
}