赞
踩
先讲个故事:从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”
百度百科是这样介绍的:
递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。
1、递归函数的参数和返回值
2、终止条件
3、递归的逻辑设计
- int factorial(int n){
- if(n==1)
- return n;
- else
- return n*factorial(n-1);
- }
- int main()
- {
- int n;
- cout<<"请输入整数:"<<endl;
- scanf("%d",&n);
- cout<<"整数:"<<n<<"的阶乘为:"<<factorial(n)<<endl;
- cout<<"\n"<<endl;
- return 0;
- }
举个例子,让你求100!。这个看着不难,不就是个连乘吧?细想头大,就是让我用计算器去敲也要半天吧。
但有了递归,这个事情就好说了:
这个可以看成二个数相乘:100×(99×98×97×……×4×3×2×1)
括号内绿色的乘积看作一个数,简单了吧。
如果你还嫌烦,括号内的数也可以同样看成二个数相乘:
99×(98×97×……×4×3×2×1)
你没有没发现点什么?对的,我们就把一个相对复杂的式子看作一个整体,不去考虑它具体的值。
大家继续思考下,如果上面的括号里我还是嫌复杂呢?是不是还可以继续分成二个数相乘呢?答案是肯定可以的。
那分解到什么时候可以直接得到答案呢?
对的,如果分解成2×1,我们就可以轻松解决了。
那么3×(2×1)也就解决了。同理:
4×(3×2×1)也就解决了。同理呢?
大家应该能想到5×(4×3×2×1)也解决了,继续扩大就可以慢慢解决。
100×(99×98×97×……×4×3×2×1)
- public void fun(参数) {
-
- if (终止条件) {
-
- return;
-
- }
-
- fun(参数);
-
- (其他判断条件或语句);
-
- }
在上边代码中,当第一次进入函数时,先判断是否符合终止条件,符合则直接结束函数,不符合入下一语句,调用自己重新进入下一层自身函数,(注意这是最外一层将不向下继续执行语句,外层卡在fun(参数处)),这个调用自己进入自身函数的操作过程即为“递”的过程。假设进入下一层后符合终止条件,返回结果,此时之前进入自身函数执行完成返回最外一层函数,最外一层函数递归调用处得到结果,(即内层函数执行完成得到结果返回值),这个过程即为“归”的过程。这时最外一层函数才能继续执行下一语句,直至函数运行完成。
1.大问题可以拆分为多个子问题。
2.原问题和拆分后的子问题除了数据规模不同,解决思路完全相同。
3.存在递归终止条件。
递归在线性数据结构中使用不太明显,迭代基本可以很容易地解决问题。
递归在非线性结构中非常重要,比如二叉树,回溯,典型的树形问题-九宫格字母组合
递归必须具备两个条件,
一是有边界,即终止条件。
二是需要调用自己。
这两个条件缺一不可,并且其中终止条件语句必须在递归调用语句之前。如果顺序颠倒则递归函数会进入死循环,永远退不出来,会出现堆栈溢出异常(StackOverflowError)。
在递归函数中,终止条件可以不止一个,递归调用也可以通过一些逻辑语句分成好几个。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。