概念
程序调用自身的编程技巧称为递归( recursion)。在数学和计算机科学中,递归指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其基本情况。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
注意
(1) 递归就是在过程或函数里调用自身;
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3)在递归调用的过程当中,系统为每一层的返回点、局部量等开辟了栈来存储,递归次数过多容易造成栈溢出等。
递归应用
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)
举例
德罗斯特效应是递归的一种视觉形式。
应用程序举例:
阶乘
<span style="font-size:18px;">public class testRecursion{
public static void main(String [] args){
System.out.println(method(10));
}
public static int method(int n){
if (n==1){
return 1;
}
else{
return n*method(n-1);
}
}
}</span>
运行结果:
3628800
斐波纳契数列(Fibonacci Sequence)是典型的递归案例,又称黄金分割数列,1、1、2、3、5、8······,接下来让我们求第20个数的值
<span style="font-size:18px;">public class testFab{
public static void main(String [] args){
System.out.println(f(20));
}
public static int f(int n){
if (n==1||n==2){
return 1;
}
else{
return f(n-1)+f(n-2);
}
}
}</span>
运行结果:
6765
递归的优缺点
优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法和调试程序带来很大方便。
缺点:递归算法解题运行效率较低,无论是耗费的计算时间还是占用的存储空间都比其他算法要多,尽管有许多数学函数均可以递归表示,但在实际应用中,递归定义的高开销往往会让人望而却步。因此,应该尽量避免使用递归,除非没有更好的算法或者在某种特定情况下递归更为适合的时候。
总结
递归算法就是一个函数通过不断对自己的调用而求得最终结果的一种思维巧妙但是开销很大的算法。递归的底层实现其实是一个栈。栈的特点是后进先出,也就是最后进入栈的事件是最先被处理的。它就像一个黑盒子,可以给我们最终的输出结果,却不用知道其内部到底经历了怎样的一个计算过程,其内部就是一个不断分解的过程,将一个复杂的计算不断拆分,变成一个嵌套一个的相同的小零件,这样可以让人很明白的理解计算的过程。