遥想当年最初面试一家公司Android岗位的时候,因为当时该司没有Android工程师,所以来面试我的是一位穿着讲究、温文尔雅的Java老大哥;
不出意外,所问之题,十之八九,皆是不熟,所以一路走下来基本都在请教,当然其中让我印象最深刻的应该就是递归的问题!
Demo codeing ~ Wait me ~
遥想最初,通过那次面试,关于递归的知识我了解到了以下几点
1.递归本身概念就是自身调用自身,专业点可能就是函数(方法)自己调用自己,其实意义是一样的~~
2.递归要给出口,否则会造成死循环
3.在很早之前手机上,如果造成这种死循环会导致手机卡死,然后直接关机
4.在我们眼前这个年代的手机上,如果造成这种死循环会导致我们APP奔溃,报出的错可能就是栈溢出,毕竟内存的空间是有限的嘛
添砖加瓦
既然抽出了时间,那么我就不仅仅只想了解那么点了,所以我要在最初的基础上为自己添砖加瓦
一个有意思的递归概念
方法或函数调用自身的方式称为递归调用,调用称为递,返回称为归
递归分类
- 直接递归 :直接递归调用就是在函数a(或过程)中直接引用(调用)函数a本身
- 间接递归 :间接递归调用就是在函数a(或过程)中调用另外一个函数b,而该函数b又引用(调用)了函数a
优缺点剖析
- 优点:代码简洁、逻辑清晰、表达力很强
- 缺点:空间复杂度高、有堆栈溢出风险、存在重复计算、过多的函数调用会耗时较多等问题
融合基础,重新整理递归思想
-
递归就是方法里调用自身
-
在使用递归策略算法时,必须有一个明确的递归结束条件,称为递归出口 ;再次提醒必须明确这个出口用来结束递归,否则会造成内存溢出,从而导致程序崩溃
-
递归算法代码简洁,但递归算法解题的运行效率较低;不是很适合用递归设计程序
-
在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储;递归次数过多容易造成栈溢出等,所以一般不提倡用递归算法设计程序
常见问题、解决方案
- 警惕堆栈溢出
可以声明一个全局变量来控制递归的深度,从而避免堆栈溢出 - 警惕重复计算
通过某种数据结构来保存已经求解过的值,从而避免重复计算
Codeing
入门级别
private String easyRecursive(int data) {
if (data == 10) {
Log.e("tag", "data=10:节日快乐,程序员~");
return "节日快乐,程序员~";
}
Log.e("tag", "data=" + data);
return easyRecursive(data + 1);
}
入门
package campu;
class Factorial {
//递归函数
int fact(int n){
if(n==1){
return 1;
}else{
return fact(n-1)*n;
}
}
}
public class TestFactorial{
public static void main(String[] args) {
Factorial factorial= new Factorial();
System.out.println("factorial(10)="+factorial.fact(10));
}
}
结束递归(未亲测)
throw new RuntimeException();
或
try{
逻辑
}catch (RuntimeException e){
}
demo
public static void recursion(int i){
for(int j = i ; 0 < j ; j--){
System.out.print(j + " ");
if(j == 5){
throw new RuntimeException();
}else {
recursion(--j);
}
}
}
for循环中设置停顿 逻辑代码中同样适用
//抛出异常
throws InterruptedException
//或者try catch操作
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
中途强制跳出递归
class Test {
static class StopMsgException extends RuntimeException {
}
public static void main(String args[]) {
try {
run(0);
} catch (StopMsgException e) {
System.out.println(e);
}
}
public static void run(int t) {
if (t > 20) {
// 跳出
throw new StopMsgException();
}
// 执行操作
System.out.println(t);
// 递归
run(t + 1);
}
}