不死神兔:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?
规律:1 1 2 2+1 3+2 5+3.。。。。。
这就是暴力美学:
//不死神兔public class text14 {
public static void main(String[] args) {
int[] a = new int[20];
a[0] = 1;
a[1] = 1;
for (int i = 2; i < a.length; i++) {
a[i] = a[i - 1] + a[i - 2];
}
System.out.println(a[19]);
}
}
递归:
public static int tu(int num) {
if (num == 1 || num == 2) return 1;
else return tu(num - 1) + tu(num - 2);
}
1.什么是递归(1)?
方法直接或者间接自己调用自己的编程技巧称为递归( recursion)
2.什么是递归死循环?
递归的方法无限调用自己,无法终止,出现栈内存溢出
3.什么是递归(2) ·?
- 方法直接调用自己或者间接调用自己的形式称为方法递归( recursion)。
- 递归做为一种算法在程序设计语言中广泛应用。
4.递归的形式:
- 直接递归:方法自己调用自己。
- 间接递归:方法调用其他方法,其他方法又回调方法自己。
public class hong {
public static void main(String[] args) {
test2();
}
public static void test() {
System.out.println("=======test被执行========");
test(); // 方法递归 直接递归形式
}
public static void test2() {
System.out.println("=======test2被执行========");
test3(); // 方法递归 间接递归
}
private static void test3() {
System.out.println("=======test3被执行========");
test2();
}
}
5.递归的弊端:
- 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象。
6.递归案例导学-计算1-n的阶乘
需求:计算1-n的阶乘的结果,使用递归思想解决,我们先从数学思维上理解递归的流程和核心点。
分析 假如我们认为存在一个公式是 f(n) = 1*2*3*4*5*6*7*…(n-1)*n; 那么公式等价形式就是: f(n) = f(n-1) *n 如果求的是 1-5的阶乘 的结果,我们手工应该应该如何应用上述公式计算。
f(5) = f(4) * 5
f(4) = f(3) * 4
f(3) = f(2) * 3
f(2) = f(1) * 2
f(1) = 1
7.递归解决问题的思路:
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归算法三要素大体可以总结为:
递归的公式: f(n) = f(n-1) * n;
递归的终结点:f(1)
递归的方向必须走向终结点:
f(5) = f(4) * 5
f(4) = f(3) * 4
f(3) = f(2) * 3
f(2) = f(1) * 2
f(1) = 1
8.案例:递归求阶乘的执行流程
9.递归算法练习(猴子吃桃)
猴子第一天摘下若干桃子,当即吃了一半,觉得好不过瘾,于是又多吃了一个 第二天又吃了前天剩余桃子数量的一半,觉得好不过瘾,于是又多吃了一个 以后每天都是吃前天剩余桃子数量的一半,觉得好不过瘾,又多吃了一个 等到第10天的时候发现桃子只有1个了。
需求:请问猴子第一天摘了多少个桃子?
分析: 整体来看,每一天都是做同一个事件,典型的规律化问题,考虑递归三要素: 递归公式: 递归终结点: 递归方向:
public static void main(String[] args) {
System.out.println(f(1));
System.out.println(f(2));
System.out.println(f(3));
}
public static int f(int n) {
if (n == 10) {
return 1;
} else {
return 2 * f(n + 1) + 2;
}
}