简介
首先要明白递归是一种算法。程序调用自身的编程技巧成为递归(recursion),它通常把一个大型复杂的问题层层转换为一个与原问题相似的规模较小的问题来求解,当递归条件不满足时,递归前进,当递归条件满足时,递归返回。其实递归不单单是我们看到的这些,他而可以是自己调用其他函数的递归。
两个条件
递归不仅仅是简单的自己调用自己,更重要的是一种解决问题的方法和思想。他的思想就在于将问题分解成为规模更小的,而且与原问题一致的问题,例如二分法就是运用了该种思想,不断的缩小范围,将问题简化,什么时候可以用递归呢?他需要满足两个条件:
●分解出来的子问题必须和原问题为一致的问题,并且必须比原问题要简单
● 递归不能无限制的调用本身,必须有一个简单的出口能使递归退出
斐波那契数列
对比上述的两个条件,斐波那契数列就非常具有代表性,在这里就响应标题,我们为什么要学好数学,高中的时候被虐过千百遍,已知a(0)=0,a(1)=1,试证明当n>2,a(n)=a(n-1)+a(n-2),记得高中数学卷子上总是有这种类型的题,想当初在此摔过很多跟头啊,有时候真是一摔不起!~现在才知道原来他是斐波那契数列,用编程很好的就验证了这种问题。
-
public class Fibonacci{
-
public static void main(String[] args){
扫描二维码关注公众号,回复: 3174766 查看本文章 -
Fibonacci fi = new Fibonacci();
-
int result = fi.fib(5);
-
}
-
public int fib(int index){
-
if(index == 1||index == 2){
-
return 1;
-
}else{
-
return fib(index-1) + fib(index-2);
-
}
-
}
-
}
在栈中分配一块空间给fi,具体在堆栈中的运行流程如下,跟着下图中的红线走,很容易发现他是一条线。
为什么用
程序员分为很多种,有的是码农,有的是高级程序员,还有的是高高在上的工程师,等等。无论是哪一种程序员,最初的时候用的较多的就是循环,什么for循环、while循环等等,有的人说递归就是一种嵌套循环,那为什么不用for循环呢?对于这个问题,元芳你怎么看?如果事情像这位仁兄说的那样,递归早就不存在了,假如当我们对一个n值不确定的序列从小到大的排序,那么我们还能用循环吗?终值不确定的情况下用循环就不太现实了。说到这里感觉好像是那么回事,上边说的都是他的优点,难道他是一个完美的人吗?没有缺点?No!当然不是,在上述的两个条件中之一就是他需要分解出更多的子问题,就是需要一步一步的递归,在学习过程中了解了堆栈的概念,在我们一步步递归的过程中,计算机就需要不断的给分配空间,在该文章一开头就说了递归是一种算法,我们都知道对于算法又有两个很重要的评估方向,一:时间复杂度,二:空间复杂度。他也是一个凡人,所以对于不同问题要不同对待。
递归的常规写法
-
void function(mode){
-
if(FirstCondition){
-
//基本项
-
}
-
else
-
{
-
function(mode) //调用自身
-
}
-
}
总结
学好数学,才能在这条道上走的更远。不要仅仅的看到他的表面,递归更重要的是一种思想,一种将问题分解成为规模更小的,而且与原问题一致的问题的思想,将问题简化。