要理解递归,首先要理解递归。
从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚对小和尚说,从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚对小和尚说,从前有座山......
上面这些梗在递归学习博客中广为流传,你读懂了,递归也就明白了。当然上面举例的笑话,很显然少了递归结束的条件,将会导致无休止的递归。
首先说明一下设计递归函数的两个要点:
1.注意“边界”的设定,即什么时候跳出递归函数
2.递归函数主体的设定(即通过哪些语句实现递归)
注:所有,记住是所有!凡是能用递归解决的问题,都可以通过归类抽象出一定的规律,这个规律适用于不同规模的问题。针对递归问题,也一定能通过数学归纳法得到与问题规模相关的函数关系。(一定注意理解!!!!)
背过上面的要点,然后我们开始今天的递归之旅~!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
先举几个简单的例子来理解递归:
- 阶乘问题
例:计算N!
int
递归是什么?最直白的解释叫做自己调用自己。观察上面的代码,我们假设计算4的阶乘,可以发现在计算4的阶乘时,又调用计算了3的阶乘,计算3的阶乘时,又调用了2的阶乘,一直到计算1的阶乘(即Factor(1)),然会返回1,返回2的阶乘,返回3的阶乘,最后return出4的阶乘。
当N=4时,每一次函数调用如下图所示,学过栈的同学是不是发现整个运算过程有点像栈,先调用的4*3!,却到最后返回结果(即出栈),最后调用的函数Factor(1)(最后入栈),最先计算完成计算(出栈)。没有问题,你的猜想没有错!递归函数本身底层的实现就是开辟了一个递归栈,不过这里不深入探讨。
引用知乎用户 @褚跃跃 制作的递归流程图
- 汉诺塔问题
汉诺塔问题(Hanoi)是几乎所有计算机相关书籍在讲到递归时,必讲的一个经典例子。可以说完全弄懂了Hanoi问题,其他的递归问题对你来说也不会有多难。
例:有一座塔,塔里面呢有三个座A,B,C,座A上放着64个大小不等的盘,其中大盘在下,小盘在上。现在有一个人,希望把盘从A移到B上,但一次只能搬一个盘,而且搬的盘只能放在其他两个盘上,且大盘不能压在小盘上。用程序模拟该过程。
新汉诺塔小游戏,在线玩,4399小游戏www.4399.com这里贴一个汉诺塔的在线游戏,先耍耍然后我们开始讨论这个经典问题。
假设我们只有3个盘子要进行搬运,那我们是不是有一个唯一的步骤不可缺少,就是在2个小盘在C上的时候,我们把大盘从A->B,然后再把两个小盘通过A移到大盘之上。你仔细想想,上述的陈述,无论你采取什么样方法去搬运,都要经历上面的操作。
那假设我们有4个盘呢,我们是不是也有一个唯一的步骤要经过,就是在3个小盘子在C上的时候,我们把大盘从A->B,然后再把3个小盘通过A从C->B。
那我们有5个盘子呢....
6个....
.......
64个........(推理过程过程是不是像极了数学归纳法)
于是乎我们发现了一个惊天的大秘密,我们的搬运过程是不是可以划分为三个阶段
1.把除了底盘以外的盘子通过B,实现移动A-C
2.将底盘移动到B
3.将C上的盘子通过A移动到B
假设“将N-1个盘子从A针移动到B针”所需次数为An-1,总移动次数为An,那么可以得出的关系就是:An=An-1x 2 + 1。我们也就可以规矩递推公式得出它的移动次数的通项即An = 2^n - 1。
那我们的c/c++代码不久应运而生?
void
如何理解汉诺塔的递归?
可以继续参考其他答主的回答,都很用心,有图形演示哟~
- 二叉树的递归遍历算法
相信学过数据结构的同学对这个算法一定不陌生
例;使用递归算法遍历二叉树
void
在一般实际问题中,递归算法使用其实并不多,但是对递归的理解是很有必要,是一种数学与计算机思维的锻炼。