Java中的递归
1.何为递归,递归与循环有何区别?
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
看了递归的定义,可能大家对递归有了大致的认识,但是也可能有人会觉得,那这样的话,递归何循环有什么区别呢,我不是只需要用循环就可以解决递归的问题了吗。
事实上并不是这样,接下来我们来看看递归和循环的区别:
递归与循环是两种不同的解决问题的典型思路。
递归算法:
优点:代码简洁、清晰,并且容易验证正确性。(如果你真的理解了算法的话,否则你更晕)
缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。
循环算法:
优点:速度快,结构简单。
缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。
递归算法 和循环算法总结
-
一般递归调用可以处理的算法,也通过循环去解决常需要额外的低效处理 。
-
现在的编译器在优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。
2.递归算法的运用
其实递归联系到数学中去就类似于数学归纳法。
例:
当n=1时等式成立
假设n=k时等式成立
此时n=k+1也成立
所以等式都成立。
接下来我们试着用递归和循环来求一下著名的数学问题斐波那契数列
斐波那契数列:斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368…
这个数列从第3项开始,每一项都等于前两项之和。
因此可写出其表达式an=an-1+an-2;
import java.util.Scanner;
public class Fibonacci {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please input this fibonacci n:");
int n = scanner.nextInt(); // 假设输入为大于零的整数
System.out.println(fibonacci(n) + ":" + fibonacciNormal(n));
int sum = 0;
for(int i = 1; i <= n; i++){
sum += fibonacci(i);
}
System.out.println(sum);
}
// 递归实现方式
public static int fibonacci(int n){
if(n <= 2){
return 1;
}else{
return fibonacci(n-1) + fibonacci(n-2);
}
}
// 递推实现方式
public static int fibonacciNormal(int n){
if(n <= 2){
return 1;
}
int n1 = 1, n2 = 1, sn = 0;
for(int i = 0; i < n - 2; i ++){
sn = n1 + n2;
n1 = n2;
n2 =