目标:递归的概述和应用理论
递归:
直接递归:自己的方法调用自己。
间接递归:自己的方法调用别的方法,别的方法又调用自己。
小结:
递归是自己调用自己。
递归如果控制的不恰当,会形成递归的死循环,从而导致栈内存溢出错误!!
递归应该防止进入递归的死循环!
public class RecursionDemo01 {
public static void main(String[] args) {
testA();
}
public static void testA(){
System.out.println("--A--");
testA();
}
}
递归的核心算法思想和执行流程(重点,拓展):
已知:f(x) = f(x - 1) + 1 (恒等式)
已知:f(1) = 1
求: f(10) = ?
计算流程:
f(10) = f(9) + 1
f(9) = f(8) + 1
f(8) = f(7) + 1
f(7) = f(6) + 1
f(6) = f(5) + 1
f(5) = f(4) + 1
f(4) = f(3) + 1
f(3) = f(2) + 1
f(2) = f(1) + 1
f(1) = 1
递归的三要素:
(1)递归的公式:f(x) = f(x - 1) + 1
(2)终结点: f(1) = 1
(3)递归的方向:必须走向终结点
public class RecursionDemo02 {
public static void main(String[] args) {
System.out.println(f(10));
}
public static int f(int x){
if(x == 1){
return 1;
}else{
return f(x - 1) + 1;
}
}
}
递归的核心思想-公式转换:
已知:f(x) = f(x + 1) + 2
f(1) = 1
求: f(10) = ?
公式转换:
f(x-1) = f(x) + 2
f(x) = f(x-1) - 2
递归算法的三要素:
(1)递归的公式: f(x) = f(x-1) - 2
(2)递归的终结点: f(1) = 1
(3)递归的方向:必须走向终结点
public class RecursionDemo03 {
public static void main(String[] args) {
System.out.println(f(10));
}
public static int f(int x){
if(x == 1){
return 1 ;
}else {
return f(x-1) - 2;
}
}
}
递归的经典案例:
猴子吃桃:
猴子第一天摘了若干个桃子,当即吃了一半,觉得好不过瘾,然后又多吃了一个。
第二天又吃了前一天剩下的一半,觉得好不过瘾,然后又多吃了一个。
以后每天都是如此
等到第十天再吃的时候发现只有1个桃子,请问猴子第一天总共摘了多少个桃子。
公式:
f(x+1) = f(x) - f(x)/2 - 1
2f(x +1) = 2f(x) - f(x) - 2
f(x) = 2f(x+1)+2
求:f(1)= ?
递归的三要素:
(1)公式: f(x) = 2f(x+1)+2
(2)终结点:f(10) = 1
(3)递归的方向:
public class RecursionDemo04 {
public static void main(String[] args) {
System.out.println(f(1));
}
public static int f(int x){
if(x == 10){
return 1 ;
}else {
return 2*f(x+1)+2;
}
}
}
案例:
1-n的和
f(n) = 1 + 2 + 3 + 4 + 5 + …n-1 + n
f(n) = f(n-1) + n
流程:
f(5) = f(4) + 5 = 1 + 2 + 3 + 4 + 5
f(4) = f(3) + 4 = 1 + 2 + 3 + 4
f(3) = f(2) + 3 = 1 + 2 + 3
f(2) = f(1) + 2 = 1 + 2
f(1) = 1
递归的核心三要素:
(1)递归的终点接: f(1) = 1
(2)递归的公式: f(n) = f(n-1) + n
(3)递归的方向必须走向终结点:
public class RecursionDemo05 {
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n){
if(n==1){
return 1;
}else{
return f(n-1) + n;
}
}
}
案例:
n的阶乘
n!= 123456…(n-1)n
f(n) = 123456…*(n-1)*n
f(n) = f(n-1)*n
f(5) = ?
流程:
f(5) = f(4) * 5 ;
f(4) = f(3) * 4 ;
f(3) = f(2) * 3 ;
f(2) = f(1) * 2 ;
f(1) = 1
递归的核心三要素:
(1)递归的终点接: f(1) = 1
(2)递归的公式 f(n) = f(n-1)*n
(3)递归的方向必须走向终结点
以上理论只能针对于规律化递归,如果是非规律化是不能套用以上公式的!
非规律化递归的问题:文件搜索,啤酒问题。
非规律化就看你的水平了!自己看着办!!
非规律化递归:啤酒问题:(作业)
啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶
,问10元可以喝多少瓶,剩余多少盖子和瓶子!! 15 3 1
public class RecursionDemo06 {
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n){
if(n == 1){
return 1 ;
}else{
return f(n-1)*n;
}
}
}