递归
(递归是重点中的重点,也是笔试和面试高频问点,仔细学习没坏处)
-
A方法调用B方法,很容易理解
-
递归是A方法调用A方法,就是自己调用自己的一个过程
-
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的但是规模更小的问题来求解,递归测了只需要少量的程序就可描述出解题过程所需的多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合
-
递归结构包括两个部分
-
递归头:什么时候跳出方法。如果没有递归头,递归将陷入死循环
这是没有递归头的报错输出"栈溢出异常"
Exception in thread "main" java.lang.StackOverflowError
这个异常是非常恐怖的,它能导致整个程序崩溃
-
递归体:什么时候需要调用自身方法
-
实例演示
最简单的递归就是计算一个数的阶乘
接下来我们演示一下用递归计算阶乘
public static void main(String[] args) {
Demo05 demo05 = new Demo05(); // 定义一个Demo05的对象demo05
int result = demo05.test(5); // 定义一个整型数据存储最后结果
System.out.println("递归结果为:"+result); // 输出结果
}
// 递归!
public static int test(int x){ // x为递归数
if(x==1){ // 边界:判断是否递归到了问题的最小规模,若是则开始直接计算,给递归数x以实质意义
return x; // 返回递归的最小计算结果
}else { // 未达到边界:问题规模还不够小,继续调用方法自身但是参数要小一个层次
return x * test(x-1); // 计算出本层递归数与下层递归返回值的计算结果,并返回给上层递归
}
// 依次类推,当递归逐步结束时,庞大的问题也得以一步步解决
}
图解递归
以阶乘递归为例:
计算x的阶乘:
递归深入阶段:main–>f(x)–>f(x-1)–>f(x-2)–>…–>f(2)–>f(1)
// 当递归深入到边界f(1)时,问题规模最小,开始直接计算并返回结果给上层递归
递归返回阶段:main<–f(x)<–f(x-1)<–…<–f(3)<–f(2)<–f(1)
注意事项
- 递归非常占用资源,所以能不用递归就不要用递归
- 递归并非是无法代替的,很多情况下可以用循环来代替
- 递归可以使用,前提是递归的基数比较小