在数学与计算机科学中,递归是指在函数的定义中使用函数自身的方法。
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。在实际编程中尤其要注意栈溢出问题。
借助递归方法,我们可以把一个相对复杂的问题转化为一个与原问题相似的规模较小的问题来求解,递归方法只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。但在带来便捷的同时,也会有一些缺点,也即:通常用递归方法的运行效率不高。
1、 Fibonacci数列
提到递归,我们可能会想到的一个实例便是斐波那契数列。斐波那契数列就是如下的数列:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …,总之,就是第N(N > 2)个数等于第(N - 1)个数和(N - 2)个数的和。用递归算法实现如下:
public static Integer fibonacci(int i) {
if (i == 0) {
return 0;
}
if (i == 1) {
return 1;
}
if (i < 0) {
return -1;
}
return fibonacci(i - 1) + fibonacci(i - 2);
}
2、阶乘
还有就是求一个数的阶乘 n!,也会用到递归,这个比较简单,直接给出实现代码,如图:
public static Integer Factorial(int i) {
if (i == 0) {
return 1;
}
return i * Factorial(i - 1);
}
public static void main(String[] args) {
System.out.println(fibonacci(6)); // 8
System.out.println(Factorial(6)); // 720
}
斐波那契数列第6个数是8 ,6的阶乘是720
3 、汉诺塔问题
汉诺塔是根据一个传说形成的数学问题:
汉诺塔示意图(图片来自网络)
有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
1、每次只能移动一个圆盘;
2、大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。
问:如何移?最少要移动多少次?
public class Demo { public static void main(String[] args) { hannoi(3, "A", "B", "C"); } public static void hannoi(int n, String from, String buffer, String to) { if (n == 1) { System.out.println("Move disk " + n + " from " + from + " to " + to); } else { hannoi(n - 1, from, to, buffer); System.out.println(("Move disk " + n + " from " + from + " to " + to)); hannoi(n - 1, buffer, from, to); } } } 控制台输出移动方法:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C